我正在推出一个网站,我想设置一个Bash单行程,所以当有人点击该网站时,它会使用内部蜂鸣器发出哔哔声。
到目前为止,它正在使用以下内容。
tail -f access_log | while read x ; do echo -ne '\007' $x '\n' ; done
Tail跟随access_log并转储到STDOUT,一次获取STDOUT行,用“\ 007”“内部蜂鸣十六进制代码”回显该行,并完成...
这就像一个美女...每次点击都会显示日志中的线条并发出哔哔声......然而,它很快就会变得烦人,所以理想情况下我希望在将tail -f /access/log
传送到while
之前对其进行过滤{1}}以便只读取我关心的行。我以为grep "/index.php"
会很好地表明游客......
这就是问题所在......
我能做到......
tail -f access_log | while read x ; do echo -ne '\007' $x '\n' ; done
一切都发出哔哔声
我可以做...
tail -f access_log | grep "/index.php"
和页面显示没有哔声,但是当我这样做时
tail -f access_log | grep "/index.php" | while read x ; do echo -ne '\007' $x '\n' ; done
没有任何事情发生,没有来自日志的行,也没有发出哔哔声。
我认为grep在某个地方搞乱了,但我无法弄清楚在哪里。 我喜欢它是一个单行,我知道它应该在脚本中完成并且会更容易,但它并不能解释为什么我认为应该工作的上述内容不是。
答案 0 :(得分:14)
Grep的输出在管道中使用时会被缓冲。使用--line-buffered
强制它使用行缓冲,以便立即输出行。
tail -f access_log | grep --line-buffered "/index.php" | while read x ; do echo -ne '\007' $x '\n' ; done
您还可以将grep
和while
循环合并为一个awk
来电:
tail -f access_log | awk '/\/index.php/ { print "\007" $0 }'
答案 1 :(得分:7)
当标准输出不是终端时,Grep缓冲输出。您需要将--line-buffered
开关传递给grep以强制它在写入一行时刷新标准输出。