LINUX.ORG.RU

Буфер при перенапралении вывода.


0

0

Захотелось сделать жизнь коллегам попроще: сделал web-интерфейс для команд ping и tshark. Online отображение результатов команды делаю через Content-type: multipart/x-mixed-replace; C HTTP частью все нормально. Но возникла проблема с чтением данных из программы. Причем проявляется оно даже на уровне чистого шела.

Если запустить команду:

tshark -n -i eth0 -c 25 host 10.0.0.1

то она нормально все показывает в "live" режиме

А если запустить ее немного подругому:

tshark -n -i eth0 -c 25 host 10.0.0.1 | cat

то вывод команды приходит реже большими кусками.

Тоесть например если из трафика сделать только пинги раз в 2 секунды. То последняя команда будет сначала долго молчать а потом выплюнет сразу 16 строк, потом опять тишина, потом еще 16 строк.

С вызовом ping xxxx | cat тоже самое, но только для случая если xxxx не отвечает - сначала тишина (даже первых строк о том что пинг начался нету) а потом сразу результат. Если xxxx пингуется то отдается результат сразу.

Что с этим можно сделать?

Если что, то код на питоне:

sys.stdout.write( "Content-type: multipart/x-mixed-replace;boundary=NEXT\n\n" )
sys.stdout.write( "--NEXT\n" )
p=os.popen("sudo /usr/bin/tshark -i eth0 -c 50 host %s"%ip,'r') 
s=p.readline()
while s:
    sys.stdout.write( "Content-type: text/html\n\n" )
    sys.stdout.write(str(datetime.datetime.today())) # for debug
    sys.stdout.write( "\t" )
    sys.stdout.write( s )
    sys.stdout.write( "\n" )
    sys.stdout.write( "--NEXT\n" )
    sys.stdout.flush()
    s=p.readline()
sys.stdout.write( "Content-type: text/plain\n\n" )
sys.stdout.write( 'tshark_done' )
sys.stdout.write( "\n" )
sys.stdout.write( "--NEXT--\n" )


Потом это разбирается на уровне javascript и рисуется в браузере. Получается прмерно так:
2008-07-01 10:53:52.057184	 15.001253    10.0.0.33 -> 10.0.0.153   ICMP Echo (ping) reply
2008-07-01 10:53:52.057365	 20.000999   10.0.0.153 -> 10.0.0.33    ICMP Echo (ping) request
2008-07-01 10:53:52.057545	 20.001402    10.0.0.33 -> 10.0.0.153   ICMP Echo (ping) reply
2008-07-01 10:53:52.057724	 25.001187   10.0.0.153 -> 10.0.0.33    ICMP Echo (ping) request
2008-07-01 10:54:27.054476	 25.001580    10.0.0.33 -> 10.0.0.153   ICMP Echo (ping) reply
2008-07-01 10:54:27.054815	 30.001392   10.0.0.153 -> 10.0.0.33    ICMP Echo (ping) request
2008-07-01 10:54:27.055022	 30.001792    10.0.0.33 -> 10.0.0.153   ICMP Echo (ping) reply
2008-07-01 10:54:27.055236	 35.001572   10.0.0.153 -> 10.0.0.33    ICMP Echo (ping) request
2008-07-01 10:54:27.055463	 35.001997    10.0.0.33 -> 10.0.0.153   ICMP Echo (ping) reply
2008-07-01 10:54:27.055661	 40.001753   10.0.0.153 -> 10.0.0.33    ICMP Echo (ping) request
2008-07-01 10:54:27.055848	 40.002220    10.0.0.33 -> 10.0.0.153   ICMP Echo (ping) reply


Тоесть readline срабатывает сразу кучей, хотя tshark пишет что пакеты приходят равномерно.

zhiltsov
() автор топика
Ответ на: комментарий от zhiltsov

у пайпа по дефолту буфер на 4К, надо покурить в эту сторону, наверное

BreadFan ★★
()
Ответ на: комментарий от zhiltsov

> Но вот у ping ничего похожего нету :(

Многие программ буферизуют stdout линейно, если он присоединен к терминалу, или блочно, если нет. Пайп заставляет их думать, что они пишут в файл. Если программа не имеет соответствующего ключика -- увы, она так написана, ничего не сделаешь...

Die-Hard ★★★★★
()
Ответ на: комментарий от zhiltsov

Может pty.spawn поможет, создает псевдо-терминал, а в нем уже запускает команду.

no1sm ★★
()

Уважаемый zhiltsov!

Напишите, пожалуйста, если Вам удалось решить эту проблему.

У меня такая же проблема: запустить через fork произвольную программу и передать через pipe ее вывод для графической отрисовки на экране.

И таже беда, что и у Вас: вижу лишь большие порции из-за буферизации (атомизации) ядром pipe файлов размеров в 4096К.

Попытки поменять свойства pipe файлов через ioctl к успеху не привели.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.