Использование подпроцесса для запуска Python script в Windows
Есть ли простой способ запуска Python script в Windows/Linux/OS X?
В последних двух, subprocess.Popen("/the/script.py")
работает, но в Windows я получаю следующую ошибку:
Traceback (most recent call last):
File "test_functional.py", line 91, in test_functional
log = tvnamerifiy(tmp)
File "test_functional.py", line 49, in tvnamerifiy
stdout = PIPE
File "C:\Python26\lib\subprocess.py", line 595, in __init__
errread, errwrite)
File "C:\Python26\lib\subprocess.py", line 804, in _execute_child
startupinfo)
WindowsError: [Error 193] %1 is not a valid Win32 application
комментарий monkut: прецедент неясен. Зачем использовать подпроцесс для запуска python script? Есть ли что-то, препятствующее вам импортировать script и вызывая необходимую функцию?
Я писал быстрый script для проверки общей функциональности инструмента командной строки Python (чтобы протестировать его на разных платформах). В основном это должно было создать кучу файлов в папке temp, запустить script на этом и проверить, что файлы были переименованы правильно.
Я мог бы импортировать script и вызывать функцию, но поскольку он полагается на sys.argv
и использует sys.exit()
, мне нужно было бы сделать что-то вроде.
import sys
import tvnamer
sys.argv.append("-b", "/the/folder")
try:
tvnamer.main()
except BaseException, errormsg:
print type(errormsg)
Кроме того, я хотел захватить stdout и stderr для отладки, если что-то пошло не так.
Конечно, лучшим способом было бы написать script более подверженным тестированию, но script в основном "сделан", и я делаю окончательную партию тестирования перед выпуском версии 1.0 (после чего я собираюсь сделать переписывание/реструктуризацию, которая будет намного более аккуратной и более проверяемой)
В принципе, было проще просто запустить script как процесс, после нахождения переменной sys.executable
. Я бы написал это как оболочку script, но это не было бы кросс-платформенным. Окончательный script можно найти здесь
Ответы
Ответ 1
Только что нашел sys.executable
- полный путь к текущему исполняемому файлу Python, который можно использовать для запуска script (вместо того, чтобы полагаться на shbang, который, очевидно, не работает в Windows)
import sys
import subprocess
theproc = subprocess.Popen([sys.executable, "myscript.py"])
theproc.communicate()
Ответ 2
Как насчет этого:
import sys
import subprocess
theproc = subprocess.Popen("myscript.py", shell = True)
theproc.communicate() # ^^^^^^^^^^^^
Это говорит subprocess
использовать оболочку ОС, чтобы открыть ваш script, и работает над тем, что вы можете просто запустить в cmd.exe.
Кроме того, это будет искать PATH для "myscript.py" - что может быть желательно.
Ответ 3
Да subprocess.Popen(cmd, ..., shell=True)
работает как шарм. В Windows распознается расширение файла .py
, поэтому Python вызывается для его обработки (на * NIX только обычная shebang). Окружение пути контролирует, видны ли вещи. Итак, первый аргумент Popen
- это просто имя script.
subprocess.Popen(['myscript.py', 'arg1', ...], ..., shell=True)
Ответ 4
Похоже, что Windows пытается запустить script, используя собственную инфраструктуру EXE, а не называть его
python /the/script.py
Попробуйте,
subprocess.Popen(["python", "/the/script.py"])
Изменить: "python" должен быть на вашем пути.
Ответ 5
Вы используете разделитель пути, который зависит от платформы. Windows использует "\", а Unix использует "/".
Ответ 6
Когда вы используете python script для окон в подпроцессе, вы должны использовать python перед именем script. Попробуйте:
process = subprocess.Popen("python /the/script.py")
Ответ 7
Например, чтобы выполнить следующее с помощью командной строки или файла BATCH, мы можем использовать это:
C:\Python27\python.exe "C:\Program files(x86)\dev_appserver.py" --host 0.0.0.0 --post 8080 "C:\blabla\"
То же самое касается Python, мы можем это сделать:
subprocess.Popen(['C:/Python27/python.exe', 'C:\\Program files(x86)\\dev_appserver.py', '--host', '0.0.0.0', '--port', '8080', 'C:\\blabla'], shell=True)
или
subprocess.Popen(['C:/Python27/python.exe', 'C:/Program files(x86)/dev_appserver.py', '--host', '0.0.0.0', '--port', '8080', 'C:/blabla'], shell=True)