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()?

142
demandé sur nbro 2011-10-07 03:44:34

1 réponses

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

  1. Définissez l'argument mot-clé shell = True ou executable = /path/to/the/shell et spécifier la commande que vous avez là.

  2. 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.

213
répondu agf 2011-10-07 00:07:10