在从 shell 脚本输出给定的行后杀死程序

Pau*_*aul 18 linux shell

背景:

我正在为一个计算生物学软件编写一个测试脚本。我正在测试的软件可能需要数天甚至数周才能运行,因此它具有内置的恢复功能,以防系统崩溃或电源故障。

我想弄清楚如何测试恢复系统。具体来说,我想不出一种以受控方式“崩溃”程序的方法。我正在考虑以某种方式在一段时间后对 SIGKILL 指令进行计时。这可能并不理想,因为不能保证测试用例每次都以相同的速度运行(它在共享环境中运行),因此将日志与所需的输出进行比较会很困难。

该软件确实为它完成的每个分析部分打印一行。

题:

我想知道是否有一种好的/优雅的方式(在 shell 脚本中)来捕获程序的输出,然后在程序输出给定的行/行数时终止程序?

dmc*_*ten 16

如果您的程序将在 SIGPIPE 上终止(这是默认操作),那么将输出通过管道传输到读取器中就足够了,读取器将在读取该行时退出。

所以它可能很简单

$ program | sed -e '/Suitable text from the line/q'
Run Code Online (Sandbox Code Playgroud)

如果你想抑制默认输出使用

$ program | sed -n -e '/Suitable text from the line/q'
Run Code Online (Sandbox Code Playgroud)

同样,如果想在一定数量的行后停止,可以使用 head 代替 sed,例如

$ program | head -n$NUMBER_OF_LINES_TO_STOP_AFTER
Run Code Online (Sandbox Code Playgroud)

正如 startdt 在评论中建议的那样,杀死发生的确切时间确实取决于终端的缓冲行为。


Kyl*_*nes 10

像这样的包装器脚本是一种标准方法。该脚本在后台运行程序,然后循环,每分钟检查日志文件中的某个字符串。如果找到该字符串,则后台程序将被终止并退出脚本。

command="prog -foo -whatever"
log="prog.log"
match="this is the what i want to match"

$command > "$log" 2>&1 &
pid=$!

while sleep 60
do
    if fgrep --quiet "$match" "$log"
    then
        kill $pid
        exit 0
    fi
done
Run Code Online (Sandbox Code Playgroud)


sta*_*rdt 7

作为 dmckee 答案的替代方法,还可以使用grep带有-m选项的命令(参见例如本手册页)命令:

compbio | grep -m 1 "Text to match"
Run Code Online (Sandbox Code Playgroud)

当找到与文本匹配的 1 行时停止或

compbio | grep -v -m 10 "Text to match"
Run Code Online (Sandbox Code Playgroud)

等待 10 行与给定文本不匹配。