2010-09-10 4 views
0

Я пишу сценарий, который прослушивает изменения в файле журнала и действует соответствующим образом. На данный момент я использую open my $fh, "tail -f $logfile |";, но в идеале я не хочу использовать системные вызовы.Есть ли эквивалент `tail -f` в Perl?

Я пробовал File::Tail, но у него минимальный интервал в 1 секунду (я пробовал меньше, но по умолчанию он равен 1 секунде, даже если я пройду 0). Я проверил источник для него и, похоже, использует sleep(), который принимает целое число. Прежде чем я попытаюсь написать свои собственные, есть ли другие варианты?

Спасибо.

+0

использует 'Time :: HiRes :: sleep', поэтому он принимает десятичные значения. –

+0

Кажется, по умолчанию 1, когда я иду ниже, хотя я должен признать, что я не приурочил его. –

ответ

6
  1. Знаете ли вы, что tail -f также использует 1-секундный сон по умолчанию? Это правда! (По крайней мере ГНУ хвоста ...)
  2. File::Tail фактически использует функцию sleepTime::HiRes «с, что означает, что параметр времени ожидания не целое число; вы можете установить его на любое дробное число секунд, с которым может справиться ваша система.
0

По моему мнению, нет ничего плохого в использовании трубы tail -f, как вы уже это сделали. Во многих ситуациях речь идет о чистоте языка, например «отсутствие системных вызовов», контрпродуктивна.

Кроме того, я видел проблемы с File::Tail в длительных процессах. К сожалению, я не могу подтвердить это утверждение с помощью каких-либо убедительных доказательств, поскольку это произошло довольно давно, я не отлаживал проблемы, вместо этого вместо использования вместо File::Tail вместо tail -F.

3

В документации есть много хорошего материала, включая ответ на этот точный вопрос. От ответа perlfaq5 «с до How do I do a "tail -f" in perl?


Сначала попробуйте

seek(GWFILE, 0, 1); 

Заявление искать (GWFILE, 0, 1) не меняет текущее положение, но это очистить по окончании срока файл на дескрипторе, так что следующий заставляет Perl снова попробовать что-то прочитать.

Если это не работает (это зависит от особенностей вашей реализации STDIO), то вам нужно что-то более, как это:

for (;;) { 
    for ($curpos = tell(GWFILE); <GWFILE>; $curpos = tell(GWFILE)) { 
    # search for some stuff and put it into files 
    } 
    # sleep for a while 
    seek(GWFILE, $curpos, 0); # seek to where we had been 
} 

Если это все еще не работает, посмотрите в метод clearerr из IO :: Handle, которая сбрасывает ошибки и состояния конца файла на дескрипторе.

Существует также модуль File :: Tail от CPAN.