Esistono quattro validi casi per preferire i metodi più specifici di Python nel osmodulo rispetto all'uso os.systemo al subprocessmodulo durante l'esecuzione di un comando:
- Ridondanza : la generazione di un altro processo è ridondante e fa perdere tempo e risorse.
- Portabilità - Molti dei metodi nel
osmodulo sono disponibili in più piattaforme mentre molti comandi della shell sono specifici del sistema operativo.
- Comprensione dei risultati : la generazione di un processo per eseguire comandi arbitrari ti costringe ad analizzare i risultati dall'output e a capire se e perché un comando ha fatto qualcosa di sbagliato.
- Sicurezza : un processo può potenzialmente eseguire qualsiasi comando impartito. Questo è un design debole e può essere evitato usando metodi specifici nel
osmodulo.
Stai effettivamente eseguendo un "intermediario" ridondante sulla strada per le eventuali chiamate di sistema ( chmodnel tuo esempio). Questo uomo di mezzo è un nuovo processo o sotto-shell.
Da os.system:
Esegui il comando (una stringa) in una subshell ...
Ed subprocessè solo un modulo per generare nuovi processi.
Puoi fare ciò di cui hai bisogno senza generare questi processi.
L' osobiettivo del modulo è fornire servizi generici del sistema operativo e la sua descrizione inizia con:
Questo modulo offre un modo portatile di utilizzare la funzionalità dipendente dal sistema operativo.
È possibile utilizzare os.listdirsia su Windows sia su Unix. Cercare di utilizzare os.system/ subprocessper questa funzionalità ti costringerà a mantenere due chiamate (per ls/ dir) e a controllare il sistema operativo in uso. Questo non è così portatile e sarà causare ancora di più la frustrazione in seguito (vedi uscita Handling ).
Comprensione dei risultati del comando:
Supponiamo di voler elencare i file in una directory.
Se stai usando os.system("ls")/ subprocess.call(['ls']), puoi solo recuperare l'output del processo, che è fondamentalmente una grande stringa con i nomi dei file.
Come puoi distinguere un file con uno spazio nel nome da due file?
Cosa succede se non si dispone dell'autorizzazione per elencare i file?
Come dovresti mappare i dati su oggetti Python?
Questi sono solo in cima alla mia testa, e mentre ci sono soluzioni a questi problemi - perché risolvere di nuovo un problema che è stato risolto per te?
Questo è un esempio del seguire il principio Don't Repeat Yourself (spesso definito come "DRY") non ripetendo un'implementazione che esiste già ed è liberamente disponibile per te.
Sicurezza:
os.systeme subprocesssono potenti. È buono quando hai bisogno di questo potere, ma è pericoloso quando non lo fai. Quando lo usi os.listdir, sai che non può fare nient'altro che elencare i file o generare un errore. Quando usi os.systemo subprocessper ottenere lo stesso comportamento puoi potenzialmente finire per fare qualcosa che non volevi fare.
Sicurezza dell'iniezione (vedi esempi di iniezione della shell ) :
Se usi l'input dell'utente come nuovo comando, in pratica gli hai dato una shell. Questo è molto simile all'iniezione SQL che fornisce all'utente una shell nel DB.
Un esempio potrebbe essere un comando del modulo:
# ... read some user input
os.system(user_input + " some continutation")
Questo può essere facilmente sfruttato per eseguire qualsiasi codice arbitrario utilizzando l'input: NASTY COMMAND;#per creare l'eventuale:
os.system("NASTY COMMAND; # some continuation")
Esistono molti di questi comandi che possono mettere a rischio il tuo sistema.