2013-07-28 10 views
7

Próbuję obsłużyć dane wyjściowe tcpdump w pythonie.Obsługa wyjścia tcpdump w pythonie

Potrzebuję uruchomić tcpdump (która przechwytuje pakiety i podaje mi informacje) i odczytuje dane wyjściowe i przetwarza je.

Problem polega na tym, że tcpdump działa nieprzerwanie i muszę przeczytać informacje o pakiecie, gdy tylko się pojawią i kontynuować.

Próbowałem zaglądać do podprocesu python i próbowałem wywoływać tcpdump używając popen i wypuszczając stdout, ale to nie działa.

Wszelkie wskazówki, jak to zrobić.

import subprocess 

def redirect(): 
    tcpdump = subprocess.Popen("sudo tcpdump...", stdin=subprocess.PIPE, stdout=subprocess.PIPE, shell=True) 
    while True: 
     s = tcpdump.stdout.readline() 
     # do domething with s 

redirect() 
+0

Czy możesz przesłać swój kod do tej pory? Dzięki. –

+0

można [użyć pseudo-tty do wymuszenia wyjścia buforowanego linii] (http://stackoverflow.com/a/12471855/4279) – jfs

Odpowiedz

14

Możesz zrobić tcpdump buforowany liniowo z "-l". Następnie możesz użyć podprocesu do przechwytywania danych wyjściowych po ich wyjściu.

import subprocess as sub 

p = sub.Popen(('sudo', 'tcpdump', '-l'), stdout=sub.PIPE) 
for row in iter(p.stdout.readline, b''): 
    print row.rstrip() # process here 
+0

używając' dla linii w iter (p.stdout.readline, b ''): print line, 'w Pythonie 2 ze względu na [błąd "buga readahead"] (http://bugs.python.org/issue3907) – jfs

+0

'dla linii w p.stdout:' wprowadza niepotrzebne opóźnienie w wyjściu na Pythonie 2 (OP chce: * "jak tylko wyjdzie "*). Użyj 'iter (..)' jak wspomniałem powyżej. Zobacz [Python: odczyt strumienia wejściowego z subprocess.communicate()] (http://stackoverflow.com/a/17698359/4279) – jfs

1

Domyślnie rury są buforowane buforowo, a interaktywne dane wyjściowe są buforowane liniowo. Wygląda na to, że potrzebujesz rury buforowanej przez linię - pochodzącej z tcpdump w podprocesie.

W dawnych czasach polecamy program "pty" Dana Bernsteina do tego rodzaju rzeczy. Dziś wydaje się, że pty nie został zaktualizowany w długim czasie, ale jest nowy program o nazwie „emtpy”, który jest mniej więcej taka sama idea: http://empty.sourceforge.net/

Można spróbować uruchomić tcpdump pod pusty w podproces aby buforował linię tcpdump, nawet jeśli pisze do potoku.

+1

python ma moduł 'pty' w stdlib. Lub można użyć 'pexpect'. Istnieją również programy 'stdbuf',' script', 'unbuffer', które mogą wymusić buforowanie wyjścia liniowego – jfs

Powiązane problemy