Я хотел обработать вывод tcpdump в скрипте на питоне и до сих пор смог добраться до этой реализации
from subprocess import Popen, PIPE, CalledProcessError
import os
import signal
import time
if __name__= = "__main__":
cmd = ["sudo","tcpdump", "-c","1000","-i","any","port","22","-n"]
with Popen(cmd, stdout=PIPE, bufsize=1, universal_newlines=True) as p:
try:
for line in p.stdout:
print(line,flush=True) # process line here
except KeyboardInterrupt:
print("Quitting")
Это то, что я понял из второго ответа на этот ранее заданный вопрос. Хотя он не ждет завершения подпроцесса для печати вывода tcpdump, я все равно получаю вывод кусками по 20-30 строк за раз. Есть ли способ прочитать, даже если в stdout pf подпроцесса есть одна строка?
PS: я запускаю этот скрипт на Raspberry Pi 4 с сервером Ubuntu 22.04.1.
tcpdump
использует больший буфер, если вы подключаете его стандартный вывод к каналу. Вы можете легко убедиться в этом, выполнив следующие две команды. (Я изменил количество с 1000 на 40 и удалил port 22
, чтобы быстро получить вывод в моей системе.)
$ sudo tcpdump -c 40 -i any -n
$ sudo tcpdump -c 40 -i any -n | cat
Первая команда печатает по одной строке за раз. Второй собирает все в буфер и печатает все, когда tcpdump
выходит. Решение состоит в том, чтобы указать tcpdump
использовать буферизацию строк с аргументом -l
.
$ sudo tcpdump -l -c 40 -i any -n | cat
Сделайте то же самое в своей программе Python.
import subprocess
cmd = ["sudo", "tcpdump", "-l", "-c", "40", "-i", "any", "-n"]
with subprocess.Popen(cmd, stdout=subprocess.PIPE, bufsize=0, text=True) as p:
for line in p.stdout:
print(line.strip())
Когда я запускаю это, я печатаю по одной строке за раз.
Обратите внимание, что universal_newlines
— это псевдоним с обратной совместимостью для text
, поэтому предпочтение следует отдавать последнему.
Кстати, код, который вы помещаете внутрь
if __name__ == '__main__':
, должен быть абсолютно тривиальным. Условие полезно только тогда, когда выimport
этот код; если весь полезный функционал будет исключен, когда выimport
, вы все равно никогда не захотите этого делать. Смотрите также stackoverflow.com/a/69778466/874188