使用正则表达式和 tail 执行命令

使用正则表达式和 tail 执行命令

如同这个问题在 Linux tcsh 中,我想跟踪日志文件,并且当我匹配正则表达式时,我想执行任意命令。我该怎么做?

答案1

在发帖人的注释中,这个问题中的一条评论引出了一篇关于使用管道时禁用自动缓冲. 解决方案是使用解除缓冲(从预计),例如:

$ 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 上,您需要安装“expect-dev”包;unbuffer 安装为“expect_unbuffer”。

注2:这是完全未经测试的并且完全有点幼稚。为了安全起见,请不要使用它。如果你确实使用了它,你可能需要用单引号括住你的正则表达式以避免shell替换/扩展。

注3:非常感谢ayrnieu完成并清理脚本。

答案2

这似乎适合一个简短的 perl 脚本:

#!/usr/bin/perl

while (<>) {
        last if /regex/;
}
system("ls");

如果您想要提供一个模式和一个带有标记参数的命令,请参阅 上的文档perldoc Getopt::Std

答案3

在我的例子中(在 RHEL 上,我想tail -n 0 -f file | grep -m 1 pattern在增长文件中出现模式时立即终止),简单的使用解除缓冲由于某种原因,Expect 包中的实用程序未能解决问题。

但根据一篇博客文章(http://www.smop.co.uk/blog/index.php/2006/06/26/tail-f-and-awk/)我发现,重定向从子 shell 中启动的 tail 的输入可以达到这样的效果:

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

但事情没那么简单。在交互式 shell 中工作时,使用 SSH 远程运行相同的命令时,仍然像往常一样冻结:

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

我发现在这种情况下,必须使用解除缓冲来自 Expect 的实用程序:

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

一定不在交互式 shell 中使用 - 取消缓冲将导致ioctl(raw): I/O error

因此,给您的建议是,如果提出的解决方案不起作用,请尝试tail -f在子 shell 中启动,如果您想在脚本或非交互式 shell 中执行此操作,则可能需要使用unbuffer或。unbuffer -p

顺便说一句,请参阅本文以详细解释输出缓冲问题:http://www.pixelbeat.org/programming/stdio_buffering/

答案4

另一种方法是使用类似样本。Swatch 的设计目的正是实现您所说的这些功能,此外还能够实现其他十几种功能。

相关内容