Почему подпроцесс ничего не возвращает при пинге сервера на Python?

Я использую подпроцесс для проверки связи с сервером, но хочу получить полный ответ. Раньше я использовал os для проверки связи, но это возвращало только 1 или 0.

Код, который я использую:

import subprocess
p = subprocess.Popen(['ping', '8.8.8.8'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
print out

Я бы хотел, чтобы был виден ответ, который я бы увидел, если бы запустил его с терминала. Обратите внимание, что я использую -c, а не -n, потому что я использую Linux в качестве ОС.

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

import subprocess
p = subprocess.Popen(['ls', '-a'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
out, err = p.communicate()
print out

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

Мой вопрос в том, как я могу получить ответ от проверки связи с сервером, назначенным переменной, которую я затем могу распечатать, как я могу, когда я запускаю ls.


person Kian Cross    schedule 07.02.2015    source источник


Ответы (2)


По умолчанию ping - это непрерывный процесс; он не останавливается, пока вы его не прервете, например с помощью ctrl-C. Конечно, с subprocess Ctrl-C невозможно.

subprocess.communicate будет буферизовать весь вывод в памяти до тех пор, пока программа заканчивается (то есть никогда); вы можете использовать его для создания ошибки нехватки памяти ;-).

Если вам просто нравится несколько пингов или даже 1, используйте параметр -c, чтобы ping:

p = subprocess.Popen(['ping', '-c1', '8.8.8.8'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

Если вам нужен непрерывный опрос, вы можете заключить его в цикл while внутри Python.

person Community    schedule 07.02.2015
comment
это неверно. Можно эмулировать Ctrl + C с подпроцессом - person jfs; 08.02.2015
comment
@ J.F.Sebastian Neat; хотя я думаю, что это не самый очевидный способ сделать это. - person ; 08.02.2015

.communicate() ожидает завершения дочернего процесса. ping с указанными аргументами не завершится, если вы явно не остановите его, например, отправьте его Ctrl + C.

Вот различные методы, позволяющие прекратить чтение вывода процесса в Python без зависания.

Если вы хотите увидеть результат, пока процесс еще выполняется; см. Python: чтение потокового ввода из subprocess.communicate ()

person jfs    schedule 07.02.2015