2015-06-24 3 views
0

Я читал много документов, но до сих пор не уверен, что я делаю неправильно.Подпроцесс Python.Popen не работает

Итак, у меня есть отдельный сценарий оболочки, который запускает отдельный сервер, а затем тот, над которым я работаю. Как только сервер подключен, я хочу запустить ls, и все. Однако по какой-либо причине stdin = subprocess.PIPE препятствует завершению команды Popen, чтобы следующая строка могла выполняться. Например, потому что код застрял Я Ctrl + C, но я получу ошибку, заявив, что wait() получил прерывание клавиатуры. Вот пример кода:

import subprocess 
from time import sleep 

p1 = subprocess.Popen("run_server", 
         stdout = subprocess.PIPE, 
         stdin = subprocess.PIPE) 
#sleep(1) 
p1.wait() 
p1.communicate(input = "ls")[0]" 

Если я заменяю p1.wait() с sleep(1), команда communicate мчит и отображает Л.С, но сценарий, который запускает сервер обнаруживает EOF на телетайп и прекращает его самостоятельно. У меня должно быть какое-то ожидание между Popen и общением, потому что серверный скрипт завершится по той же причине.

+0

Действительно ли команда «run_server», что вы вложили бы в оболочку? Нет ./run_server или что-нибудь еще? – SBH

+0

@SBHayes Да, run_server - это все. – Krin123

+0

Хорошо, я думаю, что теперь я понимаю ваш вопрос. Когда скрипт, вызывающий Popen, завершается, он также закроет все свои дочерние процессы. Чтобы ваш сервер работал, вам нужно как-то отсоединить процесс. Возможно, двойная вилка или что-то подобное. – SBH

ответ

1

p.wait() не возвращается, пока ребенок процесс мертв. Хотя родительский скрипт застрял на вызове p.wait(); ваш дочерний процесс ожидает ввода одновременно - тупика. Затем вы нажимаете Ctrl+C в оболочке; он посылает сигнал SIGINT всем процессам в группе процессов переднего плана, которая убивает как ваш родительский скрипт Python, так и подпроцесс run_server.

Вы должны бросить вызов .wait():

#!/usr/bin/env python 
from subprocess import Popen, PIPE 

p = Popen(["run_server"], stdout=PIPE, stdin=PIPE) 
output = p.communicate(b"ls")[0] 

Или в Python 3.4+:

#!/usr/bin/env python3 
from subprocess import check_output 

output = check_output(["run_server"], input=b"ls") 

Если вы хотите запустить несколько команд, а затем передать их все сразу:

input = "\n".join(["ls", "cmd2", "etc"]) # with universal_newlines=True 

Как вы знаете, прочитав subprocess docs, p.communicate() wa его для дочернего процесса выйти, и поэтому его следует вызывать не чаще одного раза. Как и с .wait(), дочерний процесс мертв после того, как .communicate() вернулся.

+0

Спасибо! У меня был только вызов 'wait' из-за характера скрипта' run_server', но в итоге соединение списка команд оказалось прекрасным, прежде чем скрипт завершился сам. Огромное спасибо! – Krin123

0

Тот факт, что когда вы Ctrl + C и ваша трассировка говорят, что вы застряли в ожидании() означает, что следующая строка выполняется, следующая строка - wait(). wait() не вернется, пока не завершится процесс p1. Однако, похоже, ваш процесс p1 не вернется, пока вы не отправите ему команду «ls» в вашем случае. Попробуйте отправить команду вызова, то ждать() .:

import subprocess 
from time import sleep 

p1 = subprocess.Popen("run_server", 
         stdout = subprocess.PIPE, 
         stdin = subprocess.PIPE) 
#sleep(1) 
p1.communicate(input = "ls")[0]" 
p1.wait() 

В противном случае, убедитесь, что ваш «run_server» сценарий завершается так что ваш сценарий может продвигаться мимо p1.wait()

+0

такой же вопрос, как я упомянул выше. Поскольку 'p1' до сих пор еще не завершен (по крайней мере, согласно сценарию' run_server', он этого не сделал), он будет использовать 'ls' как прерывание и завершить сценарий run_server и выйти из сервера. – Krin123

+0

@ Krin123 Можете ли вы объяснить это снова? Я думал, что вы хотите отправить «ls» и завершить сценарий? – SBH

+0

Извините, я думаю, что я сказал, что вводит в заблуждение.На данный момент все, что я хочу, это 'ls', поскольку это самая простая задача для запуска, но после того, как я также захочу запустить больше команд. Поэтому окончание сценария нежелательно, так как у меня есть еще много команд для запуска. – Krin123

Смежные вопросы