Je suis complètement confus entre subprocess.call()
, subprocess.Popen()
, subprocess.check_call()
.
Qui bloque et qui ne l'est pas?
Ce que je veux dire, c'est si j'utilise subprocess.Popen()
si le processus parent attend que le processus enfant attende return
/exit
avant de poursuivre son exécution.
Comment fonctionne Shell=True
affecte ces appels?
Popen
est non bloquant. call
et check_call
Bloquent. Vous pouvez créer le bloc d'instance Popen
en appelant sa méthode wait
ou communicate
.
Si vous regardez dans le code source , vous verrez que call
appelle Popen(...).wait()
, c'est pourquoi il bloque. check_call
Appelle call
, raison pour laquelle il bloque également.
À proprement parler, Shell=True
Est orthogonal à la question du blocage. Cependant, Shell=True
Oblige Python à exécuter un shell, puis à exécuter la commande dans le shell. Si vous utilisez un appel bloquant, l'appel sera renvoyé lorsque Shell se termine. Comme le shell peut générer un sous-processus pour exécuter la commande, il peut se terminer avant le sous-processus généré. Par exemple,
import subprocess
import time
proc = subprocess.Popen('ls -lRa /', Shell=True)
time.sleep(3)
proc.terminate()
proc.wait()
Deux processus sont engendrés ici: Popen génère un sous-processus exécutant le shell. Le shell génère à son tour un sous-processus exécutant ls
. proc.terminate()
tue le shell, mais le sous-processus exécutant ls
reste. (Cela se manifeste par une sortie copieuse, même après la fin du script python. Préparez-vous à tuer le ls
avec pkill ls
.).)