Esistono quattro validi casi per preferire i metodi più specifici di Python nel os
modulo rispetto all'uso os.system
o al subprocess
modulo 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
os
modulo 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
os
modulo.
Stai effettivamente eseguendo un "intermediario" ridondante sulla strada per le eventuali chiamate di sistema ( chmod
nel 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' os
obiettivo 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.listdir
sia su Windows sia su Unix. Cercare di utilizzare os.system
/ subprocess
per 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.system
e subprocess
sono 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.system
o subprocess
per 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.