一旦产生特定输出就终止进程

一旦产生特定输出就终止进程

我正在运行一个程序,它(大部分)正确执行,但随后挂起。我想运行该程序,以便一旦它输出某个字符串或停止产生输出,它就会被杀死。

我感兴趣的输出字符串是:

Was exported to:

看到这个输出后,我想自动终止该程序。或者,程序在此之后停止产生输出,因此我可以根据该条件杀死它。我怎样才能实现其中之一?

答案1

Process substitution一种选择是将此工具作为grep运行。

grep -m 1 "Was exported to:" <(<command>)

告诉-m 1grep 在第一个匹配后停止运行,一旦停止运行,里面的命令<( ... )也将被终止。但在我看来,这有点“丑陋”。

仍然使用grep,但不必运行里面的命令,就是将输出重定向到一个文件,并在后台运行它,然后用 读取该文件tail -Fgrep输出,以及kill第一次匹配后的过程。

COMMAND > $OUTPUTFILE & tail --pid=$! -n +1 -F $OUTPTFILE | (grep -q -m 1 "Was exported to:" && kill $!)

--pid=$!是为了确保tail一旦进程完成或终止,它也会停止运行。

grep但只有当您正在执行的行后面跟着换行符时,这两种方法才有效。

答案2

你可以这样做:

sh -c 'echo "$$"; exec stdbuf -oL "$0" "$@"' my-program with its args | (
  IFS= read -r pid &&
    sed '/Was exported to:/q' &&
    kill -s PIPE "$pid"
)

我们my-program在与之前运行的进程相同的进程中运行sh(并将其 pid 发送到管道)stdbuf -oL(在基于 GNU 或 FreeBSD 的系统上找到),以便恢复基于行的缓冲(应用程序倾向于在以下情况下执行基于块的缓冲):他们的输出不会发送到终端)。

在管道的另一端,sed等待Was exported to:quits 第一次出现。之后,向 pid 发送 SIGPIPE 信号,这将导致进程终止。如果没有这个kill,只有在终止my-program后向管道写入内容时才会收到 SIGPIPE 。grep

相关内容