web-dev-qa-db-fra.com

Quelle est la différence entre le sous-processus Popen et call (comment puis-je les utiliser)?

Je veux appeler un programme externe à partir 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 fonctionnent les redirections.

./my_script.sh > output

Je lis la documentation et il est dit que call() est une fonction de commodité ou une fonction de raccourci. Perdons-nous du pouvoir en utilisant call() au lieu de Popen()?

161
varunl

Il y a deux façons de faire la redirection. Les deux s'appliquent à subprocess.Popen ou subprocess.call.

  1. Définir l'argument de mot clé Shell = True ou executable = /path/to/the/Shell et spécifiez la commande telle quelle.

  2. Puisque vous ne faites que rediriger la sortie vers un fichier, définissez l'argument de mot clé.

    stdout = an_open_writeable_file_object
    

    où l'objet pointe sur le fichier output.

subprocess.Popen est plus général que subprocess.call .

Popen ne bloque pas, vous permettant d'interagir avec le processus en cours d'exécution ou de continuer avec d'autres opérations de votre programme Python. L'appel à Popen retourne un objet Popen.

call bloque . Bien qu'il prenne en charge tous les mêmes arguments que le constructeur Popen, vous pouvez toujours définir la sortie du processus, les variables d'environnement, 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 la même chose que d'appeler

returncode = Popen(*args, **kwargs).wait()

call n'est qu'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 constater, c’est une mince couche autour de Popen.

241
agf