Подтвердить что ты не робот

Использование подпроцесса для запуска 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 можно найти здесь

4b9b3361

Ответ 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)