Quelle est la différence entre le sous-processus Popen et call (Comment puis-je les utiliser)?
Je veux appeler un programme externe de Python. J'ai utilisé à la fois Popen()
et call()
pour le faire.
Quelle est la différence entre les deux?
Mon objectif spécifique est d'exécuter la commande suivante à partir de Python. Je ne sais pas comment les redirections fonctionnent.
./my_script.sh > output
J'ai lu la documentation et on dit que call()
est une fonction de commodité ou un raccourci de la fonction. Ne nous perdons toute puissance en utilisant call()
au lieu de Popen()
?
1 réponses
Il y a deux façons de faire la redirection. Les deux s'appliquent à subprocess.Popen
ou subprocess.call
.
Définissez l'argument mot-clé
shell = True
ouexecutable = /path/to/the/shell
et spécifier la commande que vous avez là.-
Puisque vous redirigez simplement la sortie vers un fichier, définissez l'argument du mot-clé
stdout = an_open_writeable_file_object
Où l'objet pointe vers le fichier
output
.
subprocess.Popen
est plus général que subprocess.call
.
Popen
ne bloque pas, vous permettant pour interagir avec le processus pendant qu'il est en cours d'exécution, ou continuer avec d'autres choses dans votre programme Python. L'appel à Popen
renvoie un objet Popen
.
call
est-ce que bloc. Bien qu'il supporte tous les mêmes arguments que le constructeur Popen
, Vous pouvez toujours définir la sortie du processus, les variables environnementales,etc., votre script attend la fin du programme et call
renvoie un code représentant l'état de sortie du processus.
returncode = call(*args, **kwargs)
Est fondamentalement le même que l'appel
returncode = Popen(*args, **kwargs).wait()
call
est juste une fonction de commodité. Son implémentation dans CPython est dans subprocess.py :
def call(*popenargs, timeout=None, **kwargs):
"""Run command with arguments. Wait for command to complete or
timeout, then return the returncode attribute.
The arguments are the same as for the Popen constructor. Example:
retcode = call(["ls", "-l"])
"""
with Popen(*popenargs, **kwargs) as p:
try:
return p.wait(timeout=timeout)
except:
p.kill()
p.wait()
raise
Comme vous pouvez le voir, c'est une fine enveloppe Popen
.