2012-08-03 16 views
9

jestem początkujący w Pythonie, i próbowałam zadzwonić app wiersza polecenia, ale nie udaje:Wywoływanie aplikacji z subprocess.call z argumentów

>>> import subprocess as s 
>>> s.call("gpio -g read 17") 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "/usr/lib/python2.6/subprocess.py", line 470, in call 
     return Popen(*popenargs, **kwargs).wait() 
    File "/usr/lib/python2.6/subprocess.py", line 623, in __init__ 
     errread, errwrite) 
    File "/usr/lib/python2.6/subprocess.py", line 1141, in _execute_child 
     raise child_exception 
OSError: [Errno 2] No such file or directory 

Ale jeśli dodać shell=True występ wszystko zaczyna działać. Czy ktoś może wyjaśnić, dlaczego?

>>> import subprocess as s 
>>> s.call("gpio -g read 17", shell=True) 
>>> 0 

Odpowiedz

24

Nie używasz połączenia w prawo. Spójrz na the introduction lub dowolny z przykładów w dokumentach. Pierwszym argumentem wywołania jest "args", sekwencja argumentów, gdzie arg [0] jest programem do uruchomienia.

Więc, kiedy to zrobić:

s.call("gpio -g read 17") 

Istnieją dwa sposoby podproces mógłby to zinterpretować. Powinien uruchomić program o nazwie "g" z argumentami "p", "i", "o", "" itp. (Pamiętaj, ciągi są ciągami znaków.) Zamiast tego może uruchomić program o nazwie "gpio -g read" 17 "bez dodatkowych argumentów. Tak czy inaczej, nie znajdzie takiego programu. (Jeśli nie masz programu o nazwie "g" lub "gpio -g read 17" na swojej zmiennej PATH, w takim przypadku zrobi on coś niewłaściwego zamiast dać błąd ...)

To czego chcesz :

s.call(["gpio", "-g", "read", "17"]) 

Dlaczego to działa, jeśli zdasz shell=True? Ponieważ cały ciąg zostaje przekazany do powłoki, która następnie wykonuje własne parsowanie wiersza poleceń i rozdziela rzeczy spacjami. To tak, jakby dzwonić pod numer os.system("gpio -g read 17").

Należy zauważyć, że wszystkie powyższe elementy są nieco uproszczone (ignoruje system Windows, a parsowanie powłoki nie jest tak naprawdę "oddzielone spacjami" itd.), Więc należy przeczytać dokumentację. (Także ten, kto napisał dokumentację subprocess jest lepszym pisarzem niż ja.)

+0

Dlaczego dodanie "shell = True" powoduje, że działa? –

+3

I z 'shell = True', to polecenie jest wysyłane do powłoki, która następnie dzieli argument dzielenia. – mgilson

+0

@MarkIngram - podobno komentowaliśmy w tym samym czasie. – mgilson