Неправильный код выхода в python при вызове сценария Windows

Кажется, я не получаю правильный код выхода из subprocess.call в Windows.

import subprocess exit_code = subprocess.call(['ant.bat', 'fail']) print exit_code # prints 0 

Выполнение того же самого в окнах, кажется, возвращает что-то другое, кроме 0

 > echo %errorlevel% 0 > ant fail > echo %errorlevel% 1 

Должны ли значения обоих вызовов давать одинаковое значение? Я делаю что-то неправильно?

В худшем случае, как проверить значение% errorlevel% в моем сценарии python?

ОБНОВИТЬ:

Я попробовал что-то вроде этого, чтобы получить значение уровня ошибки:

 environment = os.environment.copy() cmd = subprocess.Popen(['ant.bat', 'fail'], env = environment) for key, value in environment.items(): print '%s = %s' % (key, value) 

Однако я не вижу ошибки в этом словаре (os.getenv ['errorlevel'] также не работает).

Код выхода процесса и переменная среды errorlevel не совпадают:

 ant.bat: if "%1"=="batch_fail" exit /B 1 if "%1"=="proc_fail" exit 1 >>> import subprocess >>> subprocess.call(['ant.bat', 'batch_fail']) 0 >>> subprocess.call(['ant.bat', 'proc_fail']) 1 

batch_fail установит для параметра errorlevel значение 1, но оно больше не доступно после выхода оболочки. proc_fail, однако, устанавливает код выхода процесса в 1. Единственное решение, которое приходит на ум, это пакетный файл оболочки, который вызывает ant.bat и устанавливает код выхода процесса в соответствии с уровнем ошибок:

 ant_wrapper.bat: @echo off call ant.bat %1 if errorlevel 1 exit 1 >>> subprocess.call(['ant_wrapper.bat']) 0 >>> subprocess.call(['ant_wrapper.bat', 'batch_fail']) 1 >>> subprocess.call(['ant_wrapper.bat', 'proc_fail']) 1 

Редактировать:

Ваше обновление заставило меня задуматься о альтернативном подходе, используя Popen. Вы можете запустить командный файл с помощью опции cmd / K, которая будет запускать команду без выхода. Затем просто отправьте exit %errorlevel% через stdin и exit %errorlevel% ():

 #test errorlevel==1 >>> p = subprocess.Popen(['cmd', '/K', 'ant.bat', 'batch_fail'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) >>> stdoutdata, stderrdata = p.communicate(b'exit %errorlevel%\r\n') >>> p.returncode 1 #test errorlevel==0 >>> p = subprocess.Popen(['cmd', '/K', 'ant.bat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) >>> stdoutdata, stderrdata = p.communicate(b'exit %errorlevel%\r\n') >>> p.returncode 0 

Я смог получить правильное поведение, используя команду пакетного call , например

 cmd = [os.environ['COMSPEC'], '/c', 'call', bat_file] try: subprocess.check_call(cmd) except subprocess.CalledProcessError: # Error handling code 

(Я использовал subprocess.check_call но subprocess.call должен работать одинаково).

Также всегда рекомендуется поставить, if errorlevel 1 exit 1 после каждой команды в вашем пакетном скрипте, чтобы распространять ошибки (примерно эквивалент set -e s set -e ).

os.system('ant.bat fail') делает именно то, что вы хотите. Он возвращает уровень ошибок.