2012-06-21 12 views
5

Chcę usunąć liczbę zleceń z q. Polecenie usunięcia zadania to qdel JOBid.Dlaczego to polecenie działa z os.system(), ale nie z podprocesu.Popen()?

Początkowo próbowałem użyć modułu subprocess, ale mam błąd: #!/Usr/bin/env python

import sys, os, subprocess as sp 

lo = sys.argv[1] 
hi = sys.argv[2] 

lo = int(lo) 
hi = int(hi) 


for i in range(lo,hi): 
    print "i is %d"%i 
    p=sp.Popen(['qdel %d'%i],stdout=sp.PIPE) 
    #os.system('qdel %d'%i) 

Więc to nie działa. Błąd dostałam:

Traceback (most recent call last): 
File "del.py", line 14, in <module> 
p=sp.Popen(['qdel %d'%i],stdout=sp.PIPE) 
File "/usr/lib64/python2.6/subprocess.py", line 639, in __init__ 
errread, errwrite) 
File "/usr/lib64/python2.6/subprocess.py", line 1228, in _execute_child 
raise child_exception 
OSError: [Errno 2] No such file or directory 

Potem skomentowałem linię podprocesu i użyłem OS i zadziałało natychmiast. Myślę, że nie w pełni rozumiem moduł podprocesu

#!/usr/bin/env python 

import sys, os, subprocess as sp 

lo = sys.argv[1] 
hi = sys.argv[2] 

lo = int(lo) 
hi = int(hi) 


    for i in range(lo,hi): 
     print "i is %d"%i 
     #p=sp.Popen(['qdel %d'%i],stdout=sp.PIPE) 
     os.system('qdel %d'%i) 

Powyższy kod działał bezbłędnie. Chcę tylko wiedzieć, dlaczego i jakie są zalety modułu podprocesowego. Ponadto używam powłoki unixowej

Odpowiedz

3

Jeśli czytasz manual, można zobaczyć, że wezwanie do Popen jest źle: należy nie zdać jednego polecenia, ale szereg argumentów:

p=sp.Popen(['qdel', '%d'%i],stdout=sp.PIPE) 

Alternatywnie, jak sc0tt's answer Zwraca uwagę , możesz użyć shell=True, ale ma to pewne wady w bardziej złożonych przypadkach: musiałbyś ręcznie uciec wszystkie dane zmiennych w poleceniu, na wypadek gdyby zawierał, na przykład, nazwy plików ze spacjami lub coś znacznie bardziej potencjalnie szkodliwego (jak ;)

+0

Czy nadal nie musiałbyś jednak używać 'shell = True'? Jeśli nie określisz 'shell = True', czy Popen nie oczekuje, że pierwsza pozycja na liście argumentów będzie ścieżką programu do wykonania? – smont

+1

@ sc0tt Od [strona man dla 'execvp'] (http://linux.die.net/man/3/execv): Funkcje' execlp() 'i' execvp() 'będą duplikować akcje shell w poszukiwaniu pliku wykonywalnego, jeśli podana nazwa pliku nie zawiera znaku ukośnika (/). – aland

+0

@ sc0tt Przetestowałem jego odpowiedź i zadziałało. – ironcyclone

2

Chcesz użyć powłoki = True w swoim wywołaniu Popen.

p=sp.Popen(['qdel %d'%i], shell=True, stdout=sp.PIPE) 
+0

Więc jeśli powłoka była fałszywa, to gdzie próbowała wykonać polecenie? – ironcyclone

+0

@ Chris2021 Z 'shell = False', po prostu uruchamia proces za pomocą [' os.execvp() '] (http://docs.python.org/library/os.html#os.execvp). Przy 'shell = True' wywołuje domyślną powłokę i sprawia, że ​​wykonuje on dostarczony ciąg. – aland

+0

@aland Dziękuję. – ironcyclone

Powiązane problemy