Il existe quatre cas forts pour préférer les méthodes plus spécifiques de Python dans le os
module à l'utilisation de os.system
ou du subprocess
module lors de l'exécution d'une commande:
- Redondance - engendrer un autre processus est redondant et gaspille du temps et des ressources.
- Portabilité - De nombreuses méthodes du
os
module sont disponibles sur plusieurs plates-formes tandis que de nombreuses commandes shell sont spécifiques à l'OS.
- Comprendre les résultats - Le lancement d'un processus pour exécuter des commandes arbitraires vous oblige à analyser les résultats de la sortie et à comprendre si et pourquoi une commande a fait quelque chose de mal.
- Sécurité - Un processus peut potentiellement exécuter toute commande qui lui est donnée. Cette conception est faible et peut être évitée en utilisant des méthodes spécifiques dans le
os
module.
Vous exécutez en fait un "intermédiaire" redondant sur votre chemin vers les éventuels appels système ( chmod
dans votre exemple). Cet intermédiaire est un nouveau processus ou sous-shell.
De os.system
:
Exécutez la commande (une chaîne) dans un sous-shell ...
Et subprocess
c'est juste un module pour engendrer de nouveaux processus.
Vous pouvez faire ce dont vous avez besoin sans engendrer ces processus.
L' os
objectif du module est de fournir des services génériques de système d'exploitation et sa description commence par:
Ce module fournit un moyen portable d'utiliser les fonctionnalités dépendant du système d'exploitation.
Vous pouvez utiliser os.listdir
à la fois Windows et Unix. Essayer d'utiliser os.system
/ subprocess
pour cette fonctionnalité vous obligera à maintenir deux appels (pour ls
/ dir
) et à vérifier sur quel système d'exploitation vous êtes. Ce n'est pas aussi portable et va causer encore plus de frustration plus tard (voir Gestion de sortie ).
Comprendre les résultats de la commande:
Supposons que vous souhaitiez lister les fichiers dans un répertoire.
Si vous utilisez os.system("ls")
/ subprocess.call(['ls'])
, vous ne pouvez récupérer que la sortie du processus, qui est essentiellement une grande chaîne avec les noms de fichiers.
Comment pouvez-vous distinguer un fichier avec un espace dans son nom de deux fichiers?
Que faire si vous n'êtes pas autorisé à répertorier les fichiers?
Comment devez-vous mapper les données sur des objets python?
Ce ne sont que de ma tête, et bien qu'il existe des solutions à ces problèmes, pourquoi résoudre à nouveau un problème qui a été résolu pour vous?
Ceci est un exemple de suivi du principe Ne vous répétez pas (souvent appelé «DRY») en ne répétant pas une implémentation qui existe déjà et qui est librement disponible pour vous.
Sécurité:
os.system
et subprocess
sont puissants. C'est bien quand vous avez besoin de ce pouvoir, mais c'est dangereux quand vous n'en avez pas. Lorsque vous utilisez os.listdir
, vous savez qu'il ne peut rien faire d'autre que répertorier les fichiers ou générer une erreur. Lorsque vous utilisez os.system
ou subprocess
pour obtenir le même comportement, vous pouvez éventuellement finir par faire quelque chose que vous n'aviez pas l'intention de faire.
Sécurité d'injection (voir exemples d'injection de coque ) :
Si vous utilisez l'entrée de l'utilisateur comme nouvelle commande, vous lui avez essentiellement donné un shell. C'est un peu comme l'injection SQL fournissant un shell dans la base de données pour l'utilisateur.
Un exemple serait une commande de la forme:
# ... read some user input
os.system(user_input + " some continutation")
Cela peut être facilement exploité pour exécuter n'importe quel code arbitraire en utilisant l'entrée: NASTY COMMAND;#
pour créer l'éventuel:
os.system("NASTY COMMAND; # some continuation")
Il existe de nombreuses commandes de ce type qui peuvent mettre votre système en danger.