web-dev-qa-db-fra.com

Tuer un appel de sous-processus en cours d'exécution

Je lance un programme avec subprocess sur Python.

Dans certains cas, le programme peut geler. C'est hors de mon contrôle. La seule chose que je peux faire à partir de la ligne de commande à partir de laquelle il est lancé est CtrlEsc qui tue le programme rapidement.

Est-il possible d'émuler cela avec subprocess? J'utilise subprocess.Popen(cmd, Shell=True) pour lancer le programme.

12
Thomas O
p = subprocess.Popen("echo 'foo' && sleep 60 && echo 'bar'", Shell=True)
p.kill()

Consultez la documentation sur le module subprocess pour plus d'informations: http://docs.python.org/2/library/subprocess.html

16
butch

Eh bien, il existe plusieurs méthodes sur l'objet renvoyé par subprocess.Popen() qui peuvent être utiles: Popen.terminate() et Popen.kill() , qui envoient une SIGTERM et SIGKILL respectivement.

Par exemple...

import subprocess
import time

process = subprocess.Popen(cmd, Shell=True)
time.sleep(5)
process.terminate()

... mettrait fin au processus après cinq secondes.

Ou vous pouvez utiliser os.kill() pour envoyer d'autres signaux, tels que SIGINT pour simuler CTRL-C, avec ...

import subprocess
import time
import os
import signal

process = subprocess.Popen(cmd, Shell=True)
time.sleep(5)
os.kill(process.pid, signal.SIGINT)
22
Aya

Votre question n’est pas très claire, mais si je suppose que vous êtes sur le point de lancer un processus qui va à zombie et que vous voulez pouvoir le contrôler dans un état de votre script. Si tel est le cas, je vous propose ce qui suit:

p = subprocess.Popen([cmd_list], Shell=False)

Cela n’est pas vraiment recommandé de passer par Shell .. Je vous suggère d’utiliser Shell = False, vous risqueriez ainsi moins de débordement.

# Get the process id & try to terminate it gracefuly
pid = p.pid
p.terminate()

# Check if the process has really terminated & force kill if not.
try:
    os.kill(pid, 0)
    p.kill()
    print "Forced kill"
except OSError, e:
    print "Terminated gracefully"
1
ScotchAndSoda

Vous pouvez utiliser deux signaux pour tuer un appel de sous-processus en cours d'exécution, à savoir signal.SIGTERM et signal.SIGKILL; par exemple

import subprocess
import os
import signal
import time
..
process = subprocess.Popen(..)
..
# killing all processes in the group
os.killpg(process.pid, signal.SIGTERM)
time.sleep(2)
if process.poll() is None:  # Force kill if process is still alive
    time.sleep(3)
    os.killpg(process.pid, signal.SIGKILL)
0
Asif Hasnain