WINDOWS - подпроцесс python возвращает неверный код выхода сценария оболочки

Привет, ребята, я новичок в написании сценариев/питоне, но я бесконечно искал решение, но безрезультатно.

Я пытаюсь вызвать сценарий sh (используя Windows 10) с помощью python (подпроцесс) и вернуть код выхода в python.

Для ясности я удалил все, кроме соответствующего кода.

У меня есть сценарий sh 'return_value.sh', в котором буквально есть одна строка для установки кода выхода:

#!/bin/sh
exit 9

Я могу запустить это через git-bash, и он возвращает exit_code 9, как и ожидалось.

Однако, когда я пытаюсь вызвать это из python, он всегда возвращает ноль:

import subprocess
p = subprocess.Popen(['C:\Program Files\Git\git-bash.exe','return_value.sh'], stdout=subprocess.PIPE)
p.wait()
out, err = p.communicate()
print (p.returncode)    

Я искал целую вечность и не могу найти решение. Самое близкое, что я мог найти, было:

Почему иногда подпроцессу Python не удавалось получить правильный код выхода после запуска процесса?

но мне это не помогло. Кто-нибудь может дать мне несколько советов?

Большое спасибо

Майк


person Mike Waring    schedule 06.02.2018    source источник
comment
Почему shell=True, если вы передаете список в качестве первого аргумента?   -  person zvone    schedule 06.02.2018
comment
Почему shell=True никогда? В UNIX оболочка вернет статус выхода последней выполненной команды, но как пользователь UNIX я понятия не имею, верно ли это и для Windows; если это не так, то это ваша проблема.   -  person Charles Duffy    schedule 06.02.2018
comment
Также обратите внимание, что оболочка, созданная с помощью shell=True, не является той оболочкой, которую вы хотите вызвать для выполнения вашей программы; это очень разные вещи.   -  person Charles Duffy    schedule 06.02.2018
comment
Эта страница описывает cmd.exe %errorlevel% и то, как некоторые команды перезаписывают его, а некоторые перезаписывают при только ошибка, а некоторые никогда не изменят его, и, кроме того, в большинстве случаев ERRORLEVEL будет таким же, как код выхода, но есть несколько случаев с ошибками, когда это не удается. Так что да, обязательно попробуйте без оболочки... .   -  person that other guy    schedule 06.02.2018
comment
подпроцесс shell=True использует оболочку Windows %ComSpec%, которая почти всегда является cmd.exe. Если CMD может запустить return_value.sh, то это через ShellExecuteEx с использованием зарегистрированного действия открытия для файлов .sh. Это зависит от конфигурации вашей системы. Добавьте sleep или другую задержку в сценарий и проверьте дерево процессов в Process Explorer или pslist -t. Если есть промежуточные или потерянные процессы, то код выхода CMD (из cmd.exe /c "return_value.sh"), вероятно, не из процесса, который фактически выполняет скрипт.   -  person Eryk Sun    schedule 07.02.2018
comment
Кроме того, не используйте список аргументов с shell=True. Это задокументировано, но, по общему признанию, документы подпроцесса мозолят глаза.   -  person Eryk Sun    schedule 07.02.2018
comment
Спасибо за вашу помощь. Я удалил shell=True, поэтому по умолчанию должно быть false. Поскольку он вызывает сценарий sh, я не думаю, что он может работать из cmd, ему нужно что-то вроде gitbash. Поэтому я добавил путь к gitbash в список аргументов. p = subprocess.Popen(['C:\Program Files\Git\git-bash.exe', 'return_value.sh'], stdout=subprocess.PIPE) Он по-прежнему возвращает ноль, что неверно. Я проверил, что скрипт возвращает 9, вызвав его из gitbash в интерактивном режиме (используя команду sh), а затем набрав echo $? который возвращает 9. Есть еще идеи, почему это не работает? попробую на линуксе   -  person Mike Waring    schedule 08.02.2018