在Bash中如何在标准输出上触发输出?

3
我运行一个程序,该程序会向 stdout 大量写入内容。在一定时间后,该程序会向 stdout 打印一行定义好的内容,我需要触发此内容以并行调用函数(而不终止第一个程序)。

如何在 bash 中实现这个目的?


稍微解释一下:我需要运行一个安装程序,该程序是从挂载的 dvd1.iso 中的可执行文件。过一段时间后,它会打印出 "Info: Eject DVD 1 and insert DVD 2 to continue.",我需要自动完成这个操作。



根据这里提供的答案,我的测试设置如下:

talker.sh

#!/bin/bash

for VAR in {1..20}
do
    sleep 1s
    echo "huhu $VAR"
done

listener.sh

#!/bin/bash

bash talker.sh \
    | tee output.txt \
    | grep --line-buffered "huhu 3" \
    | ( while read -r line; do echo "found"; done; ) &\
    tail -f output.txt

并且它是如何工作的:
$ bash listerner.sh 
huhu 1
huhu 2
huhu 3
found
huhu 4
huhu 5
...

我不确定我理解这个问题 - 你说你的程序将一个特定的行打印到stdout,你需要触发什么...触发什么,输出这个序列吗?还是触发外部命令的执行...或者你是在问如何将某些东西作为后台进程运行? - Nunchy
1
grep | while read ? - KamilCuk
由于您的程序本身正在编写该定义行,所以您不能只是从脚本内部调用外部程序吗? - Kartik Anand
如果你想将命令作为后台进程运行,只需执行 command_name & 命令,但你应该能够从程序内部执行它。 - Nunchy
1
听起来像是 expect 的工作。它的目的正是在程序输出特定内容时执行操作。 - that other guy
@那个人 我喜欢这个 - 我会试一试! - Alex44
1个回答

4

您可以使用tee将第一个程序的输出保存到文件中,并同时过滤输出以获取所需的模式。类似于:

./program | tee output.txt | grep --line-buffered pattern | ( while read -r line; do something; done; )

正如下面@thatotherguy的评论所建议的那样,选项--line-buffered应该防止grep保留匹配项。


2
@thatotherguy 我相信现在应该已经修复了。 - francesco
1
不错!grep 可能需要 --line-buffered 以避免保留匹配项。 - that other guy
@thatotherguy 谢谢你的建议,我已经将它添加到答案中了。 - francesco
根据您的建议,我尝试了以下代码:bash test.sh | tee output.txt | grep --line-buffered "huhu 3" | ( while read -r line; do echo "found" >> output.txt; done; )test.sh 文件仅包含从1到20的循环,并输出echo。然后我查看 output.txt,总是至少会出现 found - Alex44
1
@Alex44 如果这是你尝试过的代码 ( for ((i=1;i<20;i++)); do echo outputs; done) | tee output.txt | grep --line-buffered "huhu 3" | ( while read -r line; do echo "found" >> output.txt; done; ),那么我无法重现这个问题。我建议你为 teeecho "found" >> output.txt 使用不同的文件。 - francesco
你说得对。我加了一个睡眠,这样就显示了预期的结果。干得好,伙计们!非常感谢 :) ---- ( for ((i=1;i<20;i++)); do sleep 1s; echo "huhu $i"; done) | tee output.txt | grep --line-buffered "huhu 3" | ( while read -r line; do echo "found"; done; ) - Alex44

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接