Igual a essa questão , no Linux tcsh Eu quero seguir um arquivo de log e quando eu corresponder a uma expressão regular, eu quero executar um comando arbitrário. Como posso fazer isso?
Igual a essa questão , no Linux tcsh Eu quero seguir um arquivo de log e quando eu corresponder a uma expressão regular, eu quero executar um comando arbitrário. Como posso fazer isso?
Respostas:
Na nota do pôster, um comentário nessa pergunta leva a uma postagem SO em desabilitando o buffer automático ao usar canos . A solução foi usar unbuffer (por Espero ), como em:
$ unbuffer tail -f foo | find-and-run "findwhat" "runwhat"
A resposta de wfaulk (mais a limpeza de ayrnieu) nos fornece o script 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;
Nota 1: no Debian lenny, você precisará instalar o pacote "expect-dev"; unbuffer é instalado como "expect_unbuffer".
Nota 2: isto é completamente não testado e completamente um pouco ingênuo. por segurança, não use isso. Se você usar isso, provavelmente desejará citar o seu regex para evitar a substituição / expansão do shell.
Nota 3: muito obrigado ao ayrnieu pela conclusão e limpeza do script.
Isso parece adequado para um script perl curto:
#!/usr/bin/perl
while (<>) {
last if /regex/;
}
system("ls");
Se você deseja fornecer um padrão e um comando com argumentos sinalizados, consulte a documentação em perldoc Getopt::Std
.
No meu caso (no RHEL, eu queria tail -n 0 -f file | grep -m 1 pattern
para terminar imediatamente quando ocorre um padrão no arquivo crescente), uso simples do unbuffer O utilitário do pacote Esperar não resolveu o problema por algum motivo.
Mas com base em um post no blog ( http://www.smop.co.uk/blog/index.php/2006/06/26/tail-f-and-awk/ ) Descobri que redirecionar a entrada da cauda lançada em um subshell fez o truque:
grep -m 1 pattern <(tail -n 0 -f file)
Isso não era tão simples, no entanto. Enquanto trabalhava em um shell interativo, o mesmo comando, quando executado remotamente usando o SSH, ainda congelava como de costume:
ssh login@hostname 'grep -m 1 pattern <(tail -n 0 -f file)'
Eu descobri que, neste caso, um deve unbuffer saída da cauda usando o unbuffer utilitário da Expect:
ssh login@hostname 'grep -m 1 pattern <(unbuffer -p tail -n 0 -f file)'
este Não deve ser usado em um shell interativo - o unbuffer causará ioctl(raw): I/O error
!
Então, o conselho para você é que, se as soluções propostas não funcionarem, tente lançar tail -f
em um subshell e se você quiser fazer isso em um script ou em um shell não interativo, usando unbuffer
ou unbuffer -p
pode ser necessário.
BTW, consulte este artigo para uma explicação detalhada do problema de buffer de saída: http://www.pixelbeat.org/programming/stdio_buffering/