Προγράμματα τερματικού, Termux και φορητότητα — DedSec Project
Φορητότητα CLI και Termux — απογραφή χωρίς αλλαγές Στόχος και απαιτήσεις Κατασκεύασε εργαλείο που διαβάζει τα ονόματα αρχείων από επιλεγμένο κατάλογο. Η διαδρομή μπορεί να περιλαμβάνει…
Φορητότητα CLI και Termux — απογραφή χωρίς αλλαγές
Στόχος και απαιτήσεις
Κατασκεύασε εργαλείο που διαβάζει τα ονόματα αρχείων από επιλεγμένο κατάλογο. Η διαδρομή μπορεί να περιλαμβάνει ελληνικούς χαρακτήρες και κενά. Τα ονόματα πρέπει να εμφανίζονται ταξινομημένα, προαιρετικά σε μορφή JSON, με όριο αποτελεσμάτων από 1 έως 20. Αν ο κατάλογος δεν υπάρχει ή το όριο είναι άκυρο, η λειτουργία αποτυγχάνει καθαρά. Δεν επιτρέπονται αυθαίρετες εγγραφές σε αρχεία, αιτήματα δικτύου, αλλαγές δικαιωμάτων Android ή ενημέρωση πακέτων.
Εκτελέσιμο εργαστήριο Python 3
Αποθήκευσε ως cli_lab.py και εκτέλεσε python3 cli_lab.py. Η TemporaryDirectory δημιουργεί τεχνητό φάκελο δοκιμής με ελληνικά γράμματα και ο έλεγχος καλύπτει αποδεκτές και απορριπτέες τιμές.
import argparse
import io
import json
from pathlib import Path
from tempfile import TemporaryDirectory
def main(argv, out):
parser = argparse.ArgumentParser(description='Read-only file inventory')
parser.add_argument('--root', required=True, type=Path)
parser.add_argument('--limit', type=int, default=10)
parser.add_argument('--json', action='store_true')
args = parser.parse_args(argv)
if not args.root.is_dir():
raise ValueError('root must be an existing directory')
if not 1 <= args.limit <= 20:
raise ValueError('limit must be between 1 and 20')
rows = sorted((p.name for p in args.root.iterdir() if p.is_file()))[:args.limit]
if args.json:
print(json.dumps({'files': rows}, ensure_ascii=False), file=out)
else:
for name in rows:
print(name, file=out)
return 0
with TemporaryDirectory(prefix='δοκιμή διάστημα ') as root:
home = Path(root)
(home / 'άλφα test.txt').write_text('data', encoding='utf-8')
(home / 'b.txt').write_text('', encoding='utf-8')
buf = io.StringIO()
assert main(['--root', root, '--limit', '1', '--json'], buf) == 0
assert json.loads(buf.getvalue())['files'] == ['b.txt']
for argv in (['--root', root, '--limit', '0'],
['--root', '/path/that/does/not/exist']):
try: main(argv, io.StringIO())
except ValueError: pass
else: raise AssertionError('invalid input accepted')
print('PASS cli: Unicode paths, JSON, sorting, range failures')
Πώς χωρίζονται οι ευθύνες
Η argparse αναλύει τη σύνταξη των ορισμάτων, ενώ ο έλεγχος αν υπάρχει κατάλογος και αν το όριο ανήκει στο διάστημα 1–20 αφορά τους κανόνες της εφαρμογής. Η συνάρτηση main(argv, out) δέχεται τη ροή εξόδου ως παράμετρο ώστε να ελέγχουμε το JSON χωρίς αλλαγή της καθολικής stdout. Η ταξινόμηση αποτρέπει τυχαίες διαφορές σειράς. Η pathlib.Path χειρίζεται σωστά Unicode διαδρομές, παρότι ο χρήστης πρέπει να βάζει εισαγωγικά γύρω από ονόματα με κενά στο κέλυφος. Η επιλογή ensure_ascii=False διατηρεί ευανάγνωστα ελληνικά στο JSON. Στην τελική εφαρμογή πιάσε τη ValueError εξωτερικά και εμφάνισε μήνυμα στην stderr με κωδικό εξόδου 2. Η argparse χρησιμοποιεί SystemExit για βοήθεια ή σφάλματα σύνταξης. Η Path.is_file μπορεί να ακολουθεί συμβολικούς συνδέσμους, γι' αυτό χρειάζεται ξεχωριστή απόφαση για την πολιτική τους.
Στοχευμένες ασκήσεις
- Δοκίμασε άδειο φάκελο, ελληνική διαδρομή και όνομα αρχείου με αγκύλες. Έλεγξε το ακριβές αποτέλεσμα JSON.
- Δοκίμασε --limit 0, --limit 21, ανύπαρκτο κατάλογο και --help. Σημείωσε εξαιρέσεις, μηνύματα και κωδικούς εξόδου.
- Πρόσθεσε κεντρικό χειρισμό σφαλμάτων, χωρίς να εμφανίζεται ψευδής επιτυχία σε απορριπτέο όρισμα.
- Εκτέλεσε το εργαλείο από μη εγγράψιμο κατάλογο εργασίας. Για Termux, ξεχώρισε τον ιδιωτικό χώρο της εφαρμογής από τον κοινόχρηστο αποθηκευτικό χώρο.
Παραδοτέα: μήνυμα PASS, αποτέλεσμα JSON, τουλάχιστον δύο αποτυχίες, έκδοση Python και επιβεβαίωση ότι δεν αλλάχθηκαν πραγματικά αρχεία.