Как и в этом вопросе, в Linux tcsh я хочу подключить файл журнала, а когда я сопоставляю регулярное выражение, я хочу выполнить произвольную команду. Как я могу это сделать?
4 ответа
Это кажется подходящим для короткого сценария Perl:
#!/usr/bin/perl
while (<>) {
last if /regex/;
}
system("ls");
Если вы хотите предоставить шаблон и команду с помеченными аргументами, см. Документацию в perldoc Getopt::Std
.
В примечании автора комментарий к этому вопросу приводит к 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 за завершение и очистку скрипта.
В моем случае (в 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/
Другой подход заключается в использовании такой программы, как swatch. Swatch создан именно для того, о чем вы говорите, а также для десятка других вещей.