我尝试在 Bash 脚本中执行以下操作:运行一个命令(例如tail -f log_file
),等到特定输出到达,然后停止该命令,并继续执行脚本。
我尝试了以下操作,但没有效果:
tail -f log_file | grep some_text | head -n1
我通过这种方式没有得到任何输出。
现在,我尝试诊断问题。当我简单地运行tail -n1
,然后在终端中输入一些内容时,它会在第一行之后退出。但是,如果我运行以下命令:
grep some_text | head -n1
在这种情况下,直到我按下 CTRL+D 才会得到任何输出,然后它会打印包含的输入的第一行some_text
。
我的问题是,为什么会这样?如果head
在第一种情况下立即输出第一行,那么当它从管道获取输入时为什么不这样做?它不应该在第一个情况下输出所有内容吗?n行,然后退出,并向管道的另一端发送 SIGPIPE 信号?
答案1
grep
缓冲您的输入。尝试一下grep --line-buffered
。
还有一个额外的问题,head
只有在收到第二行后才会终止,如果你的日志文件频率较低,这可能是一个问题。请参阅如何通过管道读取一行tail -f
,然后终止?。
答案2
当您在没有输入的情况下运行时tail -n1
,它将在 STDIN 输入第一行后退出,这就是它的工作方式。当您运行时,grep some_text | head -n1
您再次不向 提供任何输入grep
,因此我认为您描述的行为似乎是正常的。当您按下 CTRL D 时,您正在关闭 STDIN 管道,并head -n1
输出 `grep 从 STDIN 收到的内容。