Захотелось тут смержить вывод STDOUT и STDERR в HTML лог. Что-то вроде репорта.
Пришло в голову генерировать ещё один лог через perl скрипт, где скрипт будет вешаться отдельно и на STDOUT и на STDERR:
<STDIN> <STDERR>
123
12
12345
123
12345
123456
Соответственно, для STDIN, промежуточный лог:
<timestamp1> 0 3
<timestamp2> 3 5
<timestamp3> 8 3
<timestamp4> 11 6
для STDERR, промежуточный лог:
<timestamp5> 0 2
<timestamp6> 2 5
Первое поле — время появления текста в STDIN скрипта.
Второе поле — смещение в потоке текста из STDIN при PIPE'инге.
Третье поле — размер этого текста.
Скрипт примерно такой:
my $isEof;
my $charsRead = 0;
my $pipeCharsRead = 0;
my $overallCharsRead = 0;
my $pipeTime = 0;
while(<STDIN>)
{
$pipeTime = time();
$isEof = eof(STDIN);
while(!$isEof) {
$charsRead = read(STDIN,$subBuffer,65536);
$pipeCharsRead += $charsRead;
if($charsRead < 65536) {
$isEof = 1;
}
}
print("$pipeTime $overallCharsRead $pipeCharsRead\n");
$overallCharsRead += $pipeCharsRead;
$pipeCharsRead = 0;
}
Проблема в том, что если ему скормить PIPE вот так:
#!/bin/bash
echo 123
sleep 1
echo 12345
То обработает только последнюю строчку, что не годиться.
Повисание видимо происходит на read'е. Как правильно читать из STDIN асинхронно?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Скрипт примерно такой:
V>V>while(<STDIN>)
V>{
V> ...
V>}
V>
V>Проблема в том, что если ему скормить PIPE вот так:
V>То обработает только последнюю строчку, что не годиться.
Конструкция while (<STDIN>) { ... } уже считала первую строку в $_. Поэтому дальше read() читает следующую строку.
Вообще, для этого есть модуль
File::Tail. И ещё можно прочесть
perlfaq5 (How do I do a tail -f in perl?).