2013-07-25 19 views
22

Sto provando a scrivere un breve script in python che avvia un altro codice Python nel sottoprocesso se non è già stato avviato, altrimenti termina l'applicazione terminale & (Linux).Come terminare il processo da Python usando pid?

così sembra:

#!/usr/bin/python 
from subprocess import Popen 

text_file = open(".proc", "rb") 
dat = text_file.read() 
text_file.close() 

def do(dat): 

    text_file = open(".proc", "w") 
    p = None 

    if dat == "x" : 

     p = Popen('python StripCore.py', shell=True) 
     text_file.write(str(p.pid)) 

    else : 
     text_file.write("x") 

     p = # Assign process by pid/pid from int(dat) 
     p.terminate() 

    text_file.close() 

do(dat) 

ha problema di mancanza di conoscenza per nome proces da pid quale app si legge dal file ".proc". L'altro problema è che l'interprete dice che la stringa denominata dat non è uguale a "x" ??? Cosa mi sono perso?

+2

Perché stai passando 'shell = True'? AFAIK non è necessario nel tuo caso d'uso. Si noti inoltre che quando si usa 'shell = True' il pid restituito da' p.pid' è * not * il pid del processo python, ma il pid della shell spawn per eseguire questo processo. – Bakuriu

+0

+1 per il tuo commento, ma lo ritengo appropriato perché devo chiudere anche il terminale. – Alex

risposta

52

Utilizzando l'impressionante psutil biblioteca è abbastanza semplice:

p = psutil.Process(pid) 
p.terminate() #or p.kill() 

Se non si desidera installare una nuova libreria, è possibile utilizzare il modulo os:

import os 
import signal 

os.kill(pid, signal.SIGTERM) #or signal.SIGKILL 

Se sei interessato ad avviare il comando python StripCore.py se non è in esecuzione, e uccidendolo altrimenti, puoi usare psutil per farlo in modo affidabile LY.

Qualcosa di simile:

import psutil 
from subprocess import Popen 

for process in psutil.process_iter(): 
    if process.cmdline() == ['python', 'StripCore.py']: 
     print('Process found. Terminating it.') 
     process.terminate() 
     break 
else: 
    print('Process not found: starting it.') 
    Popen(['python', 'StripCore.py']) 

esempio di esecuzione:

$python test_strip.py #test_strip.py contains the code above 
Process not found: starting it. 
$python test_strip.py 
Process found. Terminating it. 
$python test_strip.py 
Process not found: starting it. 
$killall python 
$python test_strip.py 
Process not found: starting it. 
$python test_strip.py 
Process found. Terminating it. 
$python test_strip.py 
Process not found: starting it. 

Nota: Nelle precedenti versioni psutilcmdline era un attributo invece di un metodo.

+0

Grazie, ma il problema principale per me è come ottenere il pid dell'applicazione in esecuzione? – Alex

+3

@Alex Cosa intendi? Vorresti terminare il processo che sta eseguendo? Quindi usa semplicemente 'sys.exit()'. Se vuoi accedere al 'pid' del processo corrente usa' os.getpid() '. – Bakuriu

+0

at_Bakuriu mi scusi per favore (mi dispiace). Voglio solo creare uno script che eseguirà alcune app se non è avviato. E se l'app è avviata, per terminare questa app e anche te stesso. – Alex

2

Volevo fare la stessa cosa, ma volevo farlo in un unico file.

Quindi la logica sarebbe:

  • se uno script con il mio nome è in esecuzione, uccidetelo, quindi uscire
  • se uno script con il mio nome non è in esecuzione, fare cose

ho modificato la risposta Bakuriu e arrivato fino a questo:

from os import getpid 
from sys import argv, exit 
import psutil ## pip install psutil 

myname = argv[0] 
mypid = getpid() 
for process in psutil.process_iter(): 
    if process.pid != mypid: 
     for path in process.cmdline(): 
      if myname in path: 
       print "process found" 
       process.terminate() 
       exit() 

## your program starts here... 

Esecuzione dello script farà tutto lo script lo fa L'esecuzione di un'altra istanza dello script annullerà qualsiasi istanza esistente dello script.

Io lo uso per visualizzare un piccolo widget di calendario PyGTK che viene eseguito quando faccio clic sull'orologio. Se faccio clic e il calendario non è attivo, viene visualizzato il calendario. Se il calendario è in esecuzione e faccio clic sull'orologio, il calendario scompare.

Problemi correlati