Отладка подпроцесса. Открытый вызов - PullRequest
7 голосов
/ 05 февраля 2010

Я успешно использовал subprocess.Popen в прошлом, когда оборачивал двоичные файлы скриптом python для форматирования аргументов / настройки и т. Д. *

Разрабатывая n-ую оболочку, я сделал как обычно ... но ничего не происходит.

Вот маленький код:

print command
p = subprocess.Popen(command, shell = True)
result = p.communicate()[0]
print vars(p)
return result

А вот и вывод:

/usr/bin/sh /tmp/run/launch.sh
{'_child_created': True, 'returncode': 0, 'stdout': None, 'stdin': None, 'pid': 21650, 'stderr': None, 'universal_newlines': False}

Как видите, цель состоит в том, чтобы создать сценарий оболочки, настраивающий все, что мне нужно, и затем выполнить его. Я бы предпочел использовать настоящий код на Python, но, к сожалению, launch.sh вызывает сторонние сценарии оболочки, которые я не хочу пытаться копировать (хотя я настаиваю на Python API более года назад).

Проблема в том, что:

  • скрипт оболочки не выполняется (он должен порождать процесс и выводить некоторые мелочи)
  • исключение Python не вызывается
  • в объекте p нет ничего, что указывало бы на ошибку

Я пытался check_call, но безуспешно ...

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

EDIT:

  • Попытка запустить это в Linux (sh)
  • Оболочка необходима для подстановки переменных в вызываемых скриптах

РЕДАКТИРОВАТЬ 2:

Следуя предложению badp, я настроил код и добавил

subprocess.Popen('ps', shell = True).communicate()

Сразу после p = ... строки, которая создает процесс, вот вывод:

/usr/bin/sh /tmp/run/launch.sh
  PID TTY          TIME CMD
29978 pts/0    00:00:01 zsh
 1178 pts/0    00:00:01 python
 1180 pts/0    00:00:00 sh <defunct>
 1181 pts/0    00:00:00 ps
None

Очевидно, что процесс запущен (хотя <defunct>), и следует также отметить, что у меня есть небольшая проблема с передачей параметров в ...

Спасибо.

Ответы [ 2 ]

4 голосов
/ 05 февраля 2010

Я наконец-то нашел ответ на свой вопрос, спасибо badp и его предложениям по отладке.

Со страницы python в модуле подпроцесса :

Аргумент исполняемый файл указывает программу для выполнения. Это очень редко требуется: обычно программа для выполнения определяется аргументом args. Если shell=True, аргумент исполняемого файла указывает, какую оболочку использовать. В Unix оболочкой по умолчанию является /bin/sh. В Windows оболочка по умолчанию указывается переменной среды COMSPEC. Единственная причина, по которой вам нужно указать shell=True в Windows, - это то, где команда, которую вы хотите выполнить, фактически встроена в оболочку, например, dir, copy. Вам не нужно shell=True для запуска командного файла или запуска консольного исполняемого файла.

Поскольку я работаю в Linux и использую shell=True, моя команда на самом деле представляет собой список аргументов, которые должны выполняться исполняемым файлом , по умолчанию /bin/sh. Таким образом, была выполнена полная команда: /bin/sh /usr/bin/sh /tmp/run/launch.sh ... которая не сработала так хорошо.

И я должен был использовать либо:

subprocess.Popen('/tmp/run/launch.sh', shell=True)

или

subprocess.Popen('/tmp/run/launch.sh', executable = '/usr/bin/sh', shell=True)

Хитро, что shell=True фактически изменит значение по умолчанию исполняемый файл только в Linux ...

3 голосов
/ 05 февраля 2010

Попробуйте это:

p = subprocess.Popen(command,
                     shell = True, #is this even needed?
                     stdin = subprocess.PIPE,
                     stdout = subprocess.PIPE,
                   # stderr = subprocess.STDOUT #uncomment if reqd
                    )

Проверена работа в Windows с командой ping. Это позволяет вам communicate, что может помочь вам выяснить, почему скрипт не запускается в первую очередь:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...