Использование регулярных выражений и хвоста для выполнения команды

3965
Ross Rogers

Как и в этом вопросе, в Linux tcsh я хочу подключить файл журнала, а когда я сопоставляю регулярное выражение, я хочу выполнить произвольную команду. Как я могу это сделать?

1

4 ответа на вопрос

3
wfaulk

Это кажется подходящим для короткого сценария Perl:

#!/usr/bin/perl  while (<>) { last if /regex/; } system("ls"); 

Если вы хотите предоставить шаблон и команду с помеченными аргументами, см. Документацию по адресу perldoc Getopt::Std.

Я действительно хотел "<> пока / regex /;" работать, но я не мог этого сделать. wfaulk 14 лет назад 1
perl -Mwarnings -e 'scalar <> before / a /' - обратите внимание на предупреждение. ayrnieu 14 лет назад 1
2
quack quixote

В примечании автора комментарий к этому вопросу приводит к SO сообщению об отключении автоматической буферизации при использовании каналов . Решение состояло в том, чтобы использовать unbuffer (от ожидаемого ), как в:

$ unbuffer tail -f foo | find-and-run "findwhat" "runwhat" 

Ответ wfaulk (плюс очистка ayrnieu) предоставляет нам скрипт find-and-run:

#!/usr/bin/perl # run: find-and-run "regex-to-find" "commandtorun" die "usage: $0 <regex> <exec-this> [exec-this-arg1 ...]\n" unless @ARGV >= 2;  my ($re, @run) = @ARGV;   while (<>) { last if /$re/; } exec { $run[0] } @run; 

Примечание 1: в Debian lenny вам необходимо установить пакет «Ожидаем-dev»; unbuffer устанавливается как «hope_unbuffer».

Примечание 2: это совершенно не тестировалась и полностью слегка наивным. для безопасности не используйте это. если вы используете это, вы, вероятно, захотите заключить в кавычки свое регулярное выражение, чтобы избежать подстановки / расширения оболочки.

Примечание 3: большое спасибо ayrnieu за завершение и очистку скрипта.

die "Использование: регулярное выражение exec-this [arg1 ...] \ n", если не @ARGV> = 2; my ($ re, @run) = @ARGV; ... последний if / $ re /; ... exec {$ run [0]} @run ayrnieu 14 лет назад 1
exec / system не так важен, но $ 1 $ 2, как есть, определенно потерпит неудачу, а использование: просто хорошая идея. ayrnieu 14 лет назад 0
лучше: "использование: $ 0 [ ... ] \ П» ayrnieu 14 лет назад 1
1
Aleksander Adamowski

В моем случае (в RHEL я хотел tail -n 0 -f file | grep -m 1 patternнемедленно завершить работу, когда в растущем файле появляется шаблон), простое использование утилиты unbuffer из пакета Expect по какой-то причине не решило проблему.

Но на основании сообщения в блоге ( http://www.smop.co.uk/blog/index.php/2006/06/26/tail-f-and-awk/ ) я обнаружил, что перенаправление ввода из хвоста запущено в недолговечке сделал свое дело:

grep -m 1 pattern <(tail -n 0 -f file) 

Это было не так просто, хотя. При работе в интерактивной оболочке та же команда при удаленном запуске с использованием SSH по-прежнему зависала как обычно:

ssh login@hostname 'grep -m 1 pattern <(tail -n 0 -f file)' 

Я обнаружил, что в этом случае нужно отменить буферизацию вывода tail с помощью утилиты unbuffer из Expect:

ssh login@hostname 'grep -m 1 pattern <(unbuffer -p tail -n 0 -f file)' 

Это не должно использоваться в интерактивной оболочке - снятие буфера вызовет ioctl(raw): I/O error!

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

Кстати, см. Эту статью для подробного объяснения проблемы буферизации вывода: http://www.pixelbeat.org/programming/stdio_buffering/

0
skarface

Другой подход заключается в использовании такой программы, как swatch . Swatch создан именно для того, о чем вы говорите, а также для десятка других вещей.

Похожие вопросы