System Windows nie może znaleźć pliku w subprocess.call ()

103

Otrzymuję następujący błąd:

WindowsError: [Error 2] The system cannot find the file specified

Mój kod to:

subprocess.call(["<<executable file found in PATH>>"])

Windows 7, 64-bitowy Python 3.x najnowszy, stabilny.

Jakieś pomysły?

Dzięki,

Sri
źródło
a co to za plik wykonywalny?
SilentGhost
Wykonywalna część Android SDK
Sri
2
I jest dostępny na ścieżce
Sri
czy możesz go uruchomić z wiersza poleceń?
SilentGhost
Małe tło tego, co próbuję osiągnąć. To jest dla Opendevice - projektu open source do konwersji aplikacji HTML5 na aplikacje przeznaczone dla urządzeń. Próbuję zamienić os.system () w bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/ ... na subprocess.call ()
Sri

Odpowiedzi:

178

Kiedy polecenie jest wbudowaną powłoką, dodaj do wywołania „shell = True”.

Np. Dla dirciebie wpiszesz:

import subprocess
subprocess.call('dir', shell=True)

Cytat z dokumentacji:

Jedynym przypadkiem, w którym musisz określić shell = True w systemie Windows, jest sytuacja, gdy polecenie, które chcesz wykonać, jest wbudowane w powłokę (np. Dir lub copy). Nie potrzebujesz powłoki = True do uruchomienia pliku wsadowego lub pliku wykonywalnego opartego na konsoli.

Douglas Macdonald
źródło
14
Dzieje się tak, ponieważ nie ma wywoływanego pliku wykonywalnego, dir.exegdy istnieje /bin/lsin * nix. dirjest implementowany przez CMD.EXE, podobnie jak cdprzez bash .
Apalala,
1
Jest to stanowczo odradzane. docs.python.org/2/library/ ...
nu everest
11
@nueverest Tylko wtedy, gdy ciąg polecenia jest
Jirka,
Alternatywą (bardziej bezpieczne dla wejścia zewnętrznego) jest uzyskanie PATHod os.environi szukać go ręcznie.
asmeurer
O wiele bardziej odpowiednie rozwiązanie tego problemu można znaleźć na stronie stackoverflow.com/a/32799942/3912576 .
SimonBiggs
33

W systemie Windows uważam, że subprocessmoduł nie wygląda, PATHchyba że zdasz,shell=True ponieważ używa go CreateProcess()za kulisami. Jednak shell=Truemoże to stanowić zagrożenie dla bezpieczeństwa, jeśli przekazujesz argumenty, które mogą pochodzić spoza programu. Aby subprocessjednak móc znaleźć właściwy plik wykonywalny, możesz użyć shutil.which. Załóżmy, że plik wykonywalny w twoim PATHma nazwę frob:

subprocess.call([shutil.which('frob'), arg1, arg2])

(Działa to w Pythonie 3.3 i nowszych wersjach).

ptomato
źródło
4
Jakaś opcja Pythona 2?
Naramsim
1
Masz rację i sugerujesz, jak to naprawić. Tę odpowiedź należy przyjąć. Aktualnie przyjęta odpowiedź nie wyjaśnia przyczyny i sugeruje poprawkę, która w niektórych przypadkach może być niebezpieczna.
David Ferenczy Rogožan
18

W systemie Windows musisz zadzwonić przez cmd.exe. Jak wspomniał Apalala, polecenia systemu Windows są zaimplementowane w cmd.exe, a nie jako osobne pliki wykonywalne.

na przykład

subprocess.call(['cmd', '/c', 'dir'])

/ c mówi cmd, aby uruchomić następujące polecenie

Jest to bezpieczniejsze niż użycie shell = True, które umożliwia wstrzykiwanie powłoki.

Sam Inverso
źródło
Jak zachować otwarty ekran?
Moondra
2
@Moondra, Jeśli dobrze cię rozumiem, spróbuj /kzamiast /c. Aby cmd /?uzyskać szczegółowe informacje, wprowadź w wierszu poleceń.
Użytkownik5910,
@ User5910 Dziękuję. Spróbuję, kiedy będę miał szansę.
Moondra,
3

Jeśli używasz PowerShell, to będzie subprocess.call(['powershell','-command','dir']). Powershell obsługuje dużą część poleceń POSIX

Darksnake
źródło
2

Po długim drapaniu głowy odkryłem, że uruchomienie pliku znajdującego się w C: \ Windows \ System32 \ podczas uruchamiania 32-bitowej wersji Pythona na komputerze 64-bitowym jest potencjalnym problemem, ponieważ system Windows próbuje przechytrzyć proces, i przekierowuje wywołania do C: \ Windows \ System32 do C: \ Windows \ SysWOW64.

Przykład, jak to naprawić, znalazłem tutaj: http://code.activestate.com/recipes/578035-disable-file-system-redirector/

RBN
źródło
1

Cytat z dokumentacji:

„Przed wersją Python 3.5 te trzy funkcje obejmowały wysokopoziomowy interfejs API do podprocesu. Obecnie można używać funkcji run () w wielu przypadkach, ale wiele istniejących kodów wywołuje te funkcje”.

SO: zamiast subprocess.call użyj subprocess.run dla Pythona 3.5 i nowszych

Adrian Berca
źródło
Prawdziwe i pomocne.
Erick G. Hagstrom
0

Napotkałem ten sam problem podczas wywoływania PHP. Powodem jest to, że PHP nie jest w PATH, więc polecenie PHP nie zostało znalezione. Ale program PowerShell stwierdził, że istnieje w bieżącej lokalizacji i sugeruje zastąpienie „PHP” przez „. \ PHP”, jeśli ufam temu poleceniu. Wtedy działa dobrze.

michael xie
źródło