PDA

Visualizza la versione completa : [PYTHON] Avviare e controllare sottoprocesso


moskitoita
20-05-2007, 15:01
Ho uno script python che avvia un programma con (subprocess.Popen) e riceve da questo alcune variabili.

Mi aiutate a fare due cose:
1 vorrei che il programma che viene avviato con subprocess.Popen non si avviasse la prima volta che viene eseguito lo script (per capirci, lo script lo esegue solo se esiste un file che viene creato solo dopo la prima eseguzione dello script)
2 vorrei che dopo 40 secondi fosse chiuso quel programma avviato con subprocess.Popen


So che l'erba voglio non cresce neanche nel giardino del re, cerco solo dritte :D

moskitoita
20-05-2007, 15:53
Per semplificare:
Come si può mettere un tempo di timeout per uno script?
Come si fa un ciclo if basato sull'esistenza di un file?


Grazie

billiejoex
20-05-2007, 22:52
1 vorrei che il programma che viene avviato con subprocess.Popen non si avviasse la prima volta che viene eseguito lo script (per capirci, lo script lo esegue solo se esiste un file che viene creato solo dopo la prima eseguzione dello script)
E cosa non sai fare di preciso?
Usa os.path.exists() per verificare se il file esiste o meno.
Se non esiste lo crei ( open('nome_file', 'w') ) e forzi l'uscita con sys.exit().
Se esiste lanci la Popen e fai quello che devi fare.


2 vorrei che dopo 40 secondi fosse chiuso quel programma avviato con subprocess.Popen
Uhm... qui gia un po' più difficile.
Potresti killare il processo dato il pid. Non è molto elegante e perdi in portabilità ma cmq funziona.

Per Windows usando pywin32 (da installare a parte):


import subprocess
import time
import win32api

command = 'C:\\eseguibile.exe'
pipe = subprocess.Popen(command, stdout=subprocess.PIPE)
time.sleep(40)
win32api.TerminateProcess(int(pipe._handle), -1)

Per Windows usando ctypes (non devi installare nulla con python 2.5 o superiore):


import subprocess
import time
import ctypes

command = 'C:\\dc.exe'
pipe = subprocess.Popen(command, stdout=subprocess.PIPE)
time.sleep(40)
ctypes.windll.kernel32.TerminateProcess(int(pipe._ handle), -1)

Per UNIX usando banalmente os.kill:


import subprocess
import time
import os

command = '/usr/bin/eseguibile'
pipe = subprocess.Popen(command, stdout=subprocess.PIPE)
time.sleep(40)
os.kill(int(pipe._handle))


Come si può mettere un tempo di timeout per uno script?
In che senso? time.sleep() non ti basta?


Come si fa un ciclo if basato sull'esistenza di un file?


import os

if os.path.exists('file'):
....
else:
....

moskitoita
21-05-2007, 12:26
Sei gentilissimo, ho risolto molti dei problemi; ma uno persiste:
Lancio questo (http://cl1p.net/ldm/) script come sottoprocesso che apre una finestra di login e aspetta l'input.
Io vorrei che dopo tot secondi si chiudesse, ho provato sia con

time.sleep(40)
os.kill(int(pipe._handle))
nello script che lo lancia, sia con

def suicide():
sys.exit()

t = threading.Timer(1.0, suicide)
t.start()
nello script stesso

Idee???

billiejoex
21-05-2007, 12:59
Non ho capito bene quale sia il problema ma personalmente ritengo che utilizzare i sotto processi sia una cattiva abitudine da evitare, quando possibile, sopratutto considerando che il processo che lanci è un sorgente python che puoi benissimo richiamare e gestire dal tuo sorgente principale.
Molto meglio richiamare quel sorgente sotto forma di modulo, eventualmente applicando qualche modifica al suo interno. Esempio:


import modulo
modulo.start()
...
...
...
modulo.stop()

moskitoita
21-05-2007, 13:21
Sto modificando gli script di login di un sistema client/server chiamato ltsp; quindi vorrei cambiare il meno possibile.

Lo script che ti ho postato chiede username e password per il login, come faccio a far si che si chiuda dopo 30 secondi???

billiejoex
21-05-2007, 13:55
Sto modificando gli script di login di un sistema client/server chiamato ltsp; quindi vorrei cambiare il meno possibile.
Lo script che ti ho postato chiede username e password per il login, come faccio a far si che si chiuda dopo 30 secondi???
Come credi.
In questo caso vale quanto detto sopra, usa subprocess.Popen dandogli come primo parametro una tupla contente:
- path dell'interprete Python
- lo script che desideri lanciare:


pipe = subprocess.Popen(('/usr/bin/python', 'script.py'), stdout=subprocess.PIPE)

Successivamente esegui il conteggio di 30 secondi tramite time.sleep() o threading.Timer nel caso in cui desideri che il codice non si blocchi, infine os.kill() sul PID per terminare il sotto processo.

Saluti

Loading