Windows не может найти файл в subprocess.call ()

103

Я получаю следующую ошибку:

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

Мой код:

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

Windows 7, 64 бит. Python 3.x последняя, ​​стабильная.

Любые идеи?

Спасибо,

Шри
источник
а что это за исполняемый файл?
SilentGhost
"Андроид" исполняемая часть Android SDK
Sri
2
И это есть доступна на PATH
Sri
вы можете запустить его из командной строки?
SilentGhost
Немного предыстории того, чего я пытаюсь достичь. Это для Opendevice - проекта с открытым исходным кодом для преобразования приложений HTML5 в приложения для конкретных устройств. Я пытаюсь заменить os.system () в bitbucket.org/srirangan/opendevice/src/tip/tools/net/srirangan/… на subprocess.call ()
Шри

Ответы:

179

Если команда является встроенной оболочкой, добавьте к вызову 'shell = True'.

Например, dirвы должны ввести:

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

Цитата из документации:

Единственный раз, когда вам нужно указать shell = True в Windows, - это когда команда, которую вы хотите выполнить, встроена в оболочку (например, dir или copy). Shell = True не требуется для запуска командного файла или исполняемого файла на основе консоли.

Дуглас Макдональд
источник
14
Это потому, что исполняемый файл не вызывается, dir.exeпока есть /bin/lsin * nix. dirреализуется CMD.EXE так же, как cdреализовано в bash .
Apalala
1
Это настоятельно не рекомендуется. docs.python.org/2/library/…
nu everest
11
@nueverest Только когда командная строка построена из внешнего ввода
Jirka
Альтернатива (более безопасная для внешнего входа), чтобы получить PATHот os.environи поиска вручную.
asmeurer
См. Stackoverflow.com/a/32799942/3912576 для более подходящего решения этой проблемы.
SimonBiggs
34

В Windows я считаю, что subprocessмодуль не смотрится, PATHпока вы не пройдете,shell=True потому что он используется CreateProcess()за кулисами. Однако это shell=Trueможет представлять угрозу безопасности, если вы передаете аргументы, которые могут исходить извне вашей программы. Чтобы, subprocessтем не менее, найти правильный исполняемый файл, вы можете использовать shutil.which. Предположим, исполняемый файл в вашем PATHназвании frob:

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

(Это работает на Python 3.3 и выше.)

Помидор
источник
4
Любой вариант python 2?
Naramsim
1
Вы правы и предлагаете правильный способ исправить это. Этот ответ следует принять. Принятый в настоящее время ответ не объясняет причину и предлагает исправление, которое в некоторых случаях может быть опасным.
Давид Ференци Рогожан
18

В Windows нужно звонить через cmd.exe. Как упоминалось в Apalala, команды Windows реализованы в cmd.exe, а не как отдельные исполняемые файлы.

например

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

/ c указывает cmd запустить следующую команду

Это безопаснее, чем использование shell = True, которое допускает инъекции оболочки.

Сэм Инверсо
источник
Как мне держать экран открытым?
Moondra
2
@Moondra, Если я вас правильно понял, попробуйте /kвместо /c. cmd /?Для получения подробной информации введите в командной строке.
User5910
@ User5910 Спасибо. Я попробую, когда у меня будет возможность.
Moondra
3

Если вы используете powershell, то в нем будет subprocess.call(['powershell','-command','dir']). Powershell поддерживает большую часть команд POSIX.

Darksnake
источник
2

После долгих размышлений я обнаружил, что запуск файла, который находится в C: \ Windows \ System32 \ при запуске 32-битной версии python на 64-битной машине, является потенциальной проблемой из-за того, что Windows пытается перехитрить процесс, и перенаправить вызовы с C: \ Windows \ System32 на C: \ Windows \ SysWOW64.

Я нашел здесь пример того, как это исправить: http://code.activestate.com/recipes/578035-disable-file-system-redirector/

RBN
источник
1

Цитата из документации:

«До Python 3.5 эти три функции составляли высокоуровневый API для подпроцессов. Теперь вы можете использовать run () во многих случаях, но многие существующие коды вызывают эти функции».

SO: вместо subprocess.call используйте subprocess.run для Python 3.5 и выше.

Адриан Берка
источник
Верно и полезно.
Эрик Г. Хагстром,
0

Я столкнулся с той же проблемой, когда звонил на PHP. Причина в том, что PHP отсутствует в PATH, поэтому команда PHP не найдена. Но PowerShell обнаружил, что он действительно существует в текущем местоположении, и предлагает заменить «PHP» на «. \ PHP», если я доверяю этой команде. Тогда все идет хорошо.

Майкл Се
источник