python - вызов подпроцесса не прерывается при использовании каналов - PullRequest
2 голосов
/ 24 декабря 2010

У меня странная проблема с python 2.6.5.Если я вызываю

p = subprocess.Popen(["ifup eth0"], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

с отключенным интерфейсом eth0, программа python зависает."p.communicate ()" занимает минуту или больше, чтобы закончить.Если интерфейс подключен раньше, программа работает без сбоев.Я проверил «ifup eth0» из командной строки вручную для обоих случаев и молниеносно.

Если у вас есть идеи, в чем может быть проблема, я был бы очень признателен.

Спасибозаранее

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

Исходя из ответов, я попробовал следующие вещи:

p = subprocess.Popen(["ifup", "eth0"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

Если интерфейс был ранее,Скрипт работает без сбоев.Однако, если интерфейс не работает, Python снова зависает.Я также попробовал:

p = subprocess.Popen(["ifup", "eth0"], shell=False)
out, err = p.communicate()

И ВСЕ работает идеально быстро.Поэтому это может быть действительно связано с тупиком, как указывало на функтку.Однако в документации по питону также сказано: python ref :

Предупреждение

Это приведет к взаимоблокировке при использовании stdout = PIPE и / или stderr = PIPE и дочерний процесс генерируетдостаточно вывода в канал, чтобы он блокировал ожидание буфера канала ОС для приема большего количества данных.Чтобы избежать этого, используйте функцию connect ().

Поэтому тупика не должно быть.Хм ... Вот подробный вывод, когда я запускаю программы в командной строке:

1 Кейс, интерфейс eth0 уже запущен:

ifup eth0
Interface eth0 already configured

2 Кейс, интерфейс до:

ifup eth0 
ssh stop/waiting
ssh start/running

Таким образом, команда ifup генерирует две строки выхода в случае, если интерфейс не работает ранее, и одну строку выхода в противном случае.Это единственное отличие, которое я заметил.Но я сомневаюсь, что это является причиной проблемы, так как "ls -ahl" вызывает намного больше строк вывода и работает очень хорошо.

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

У вас есть идеи, что может быть причиной этого?Или это, вероятно, ошибка в обработке Python Pipe или самой команды ifup?Действительно ли мне нужно использовать старый os.popen (cmd) .read () ????

EDIT2:

os.popen (cmd) .read() страдает от той же проблемы.Любая идея о том, как я могу проверить поведение канала ifup в командной строке?

Я ценю каждый совет, заранее спасибо

Ответы [ 3 ]

2 голосов
/ 24 декабря 2010

Вы должны проверить предупреждение по методу subprocess.call.Это может быть причиной вашей проблемы.

Предупреждение

Как и Popen.wait (), это приведет к тупику при использовании stdout = PIPE и / или stderr= PIPE, а дочерний процесс генерирует достаточное количество выходных данных для канала, так что он блокирует ожидание, пока буфер канала ОС не примет больше данных.

1 голос
/ 02 декабря 2014

/ etc / network / if-up.d / ntpdate не отсоединяется правильно

Вот почему read () ожидает закрытия fds (stdin / stdout / stderr). Вы можете отсоединить stdin / stderr / stdout (не добавляйте stdout = subprocess.PIPE и то же самое к вызову конструктора Popen).

1 голос
/ 24 декабря 2010
p = subprocess.Popen(["ifup", "eth0"], shell=False, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()

Установите shell=False, вам это не нужно.

Попробуйте запустить этот код, он должен работать. Обратите внимание, что два аргумента являются отдельными элементами в списке.

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