从 RHEL5 或 RHEL6 上的管道读取时为什么read -t
不超时?
这是我的示例,它在从管道读取时不会在我的 RHEL 盒子上超时:
tail -f logfile.log | grep 'something' | read -t 3 variable
如果我是正确的read -t 3
应该在 3 秒后超时?
提前谢谢了。
克里斯
GNU bash, version 4.1.2(1)-release (x86_64-redhat-linux-gnu)
chepner 给出的解决方案应该有效。
解释为什么您的版本不简单:当您构建像您这样的管道时,数据从左到右通过管道流动。但是,当您read
超时时,左侧的程序将继续运行,直到它们注意到管道已损坏,并且仅当它们尝试写入管道时才会发生这种情况。
一个简单的例子是这样的:
cat | sleep 5
五秒钟后,管道将被破坏,因为sleep
将退出,但cat
仍会继续运行,直到您按回车键。
在您的情况下,这意味着在 grep 产生结果之前,尽管超时,您的命令仍将继续运行。
虽然不能直接回答您的具体问题,但您需要运行类似
read -t 3 variable < <( tail -f logfile.log | grep "something" )
为了variable
在管道完成后新设置的值可见。看看这是否按预期超时。
由于您只是read
用作在固定时间后退出管道的一种方式,因此您不必担心variable
. 但是,grep
由于其自身的内部缓冲,可能会在超时内不打印而找到匹配项。您可以使用以下选项禁用它(GNU grep
至少使用 ) :--line-buffered
tail -f logfile.log | grep --line-buffered "something" | read -t 3
另一个选项(如果可用)是该timeout
命令作为替代read
:
timeout 3 tail -f logfile.log | grep -q --line-buffered "something"
在这里,我们在 3 秒后杀死,并以通常的方式tail
使用退出状态。grep
我现在没有 RHEL 服务器来测试您的脚本,但我敢打赌 read 会在超时时退出并正常工作。尝试运行:
grep 'something' | strace bash -c "read -t 3 variable"
你可以确认一下。