Bash 如何在管道中有条件地执行/终止命令

Bash 如何在管道中有条件地执行/终止命令,bash,shell,Bash,Shell,我正在编写一个脚本,它需要检测程序中对FFMPEG的第一次调用,并从那时起运行一个脚本 核心代码如下: strace -f -etrace=execve <program> 2>&1 | grep <some_pattern> | <run_some_script> strace-f-etrace=execve 2>&1|grep| 期望的行为是,当第一个greped结果出来时,脚本应该启动。如果在终止之前没有匹配,则应忽略脚本 主要问题是如

我正在编写一个脚本,它需要检测程序中对FFMPEG的第一次调用,并从那时起运行一个脚本

核心代码如下:

strace -f -etrace=execve <program> 2>&1 | grep <some_pattern> | <run_some_script>
strace-f-etrace=execve 2>&1|grep|
期望的行为是,当第一个greped结果出来时,脚本应该启动。如果在
终止之前没有匹配,则应忽略脚本

主要问题是如何基于grep的输出有条件地执行脚本,以及如何在程序终止后终止脚本

我认为第一个问题可以通过read解决,因为greped文本被用作信号,其内容是不相关的:

... | read -N 1 && <run_some_script>
…|读取-n1&&
第二个问题可以通过断管机制解决:

<run_some_script> > >(...)
(…)
但我不知道如何让他们一起工作。或者有更好的解决方案吗?

您可以要求
grep
只匹配一次模式,然后返回并使其返回成功错误代码。将其放在一个if条件中,作为

if strace -f -etrace=execve <program> 2>&1 | grep -q <some_pattern>; then
    echo 'run a program'
fi
Use
coproc
与在后台运行命令类似,但提供了一种捕获命令运行输出的简单方法

coproc outputfd { wrapper; }
现在,通过读取
coproc
提供的文件描述符,观察
wrapper
中运行的命令的输出。下面的代码将监视输出和
模式的第一次匹配,它启动后台作业以运行命令,进程id存储在
pid

flag=1
while IFS= read -r -u "${outputfd[0]}" output; do
    if [[ $output == *"pattern"* && $flag -eq 1 ]]; then
        flag=0
        command_to_run & pid=$!
    fi
done
当循环终止时,这意味着由
coproc
启动的后台作业完成。在这一点上,脚本启动了。为了安全起见,看看它是否还活着,然后杀掉它

kill "$pid" >/dev/null 2>&1
使用:

strace-f-etrace=execve 2>&1|
格雷普·伊夫内

-q
意味着
-m1
——它在看到单个匹配时立即退出。感谢您的回答。也许我不清楚,但我需要脚本在strace完成之前开始。我希望“execve”(“ffmpeg…)”调用触发脚本,grep只是我在运行时检测它的方法。我正在使用RPI为我记录一些实时流。录制脚本使用python工具,当存在有效流时,该工具将调用ffmpeg进行实际录制。我想做的是,当录制开始时,我可以运行脚本在GPIO设备上显示一些动态信息,并在录制完成后关闭该设备。所以脚本不应该在strace终止后运行。如果我没看错的话,在grep匹配结果后,你代码中的strace将收到一个SIGPIPE,这将过早地杀死strace。@YenvY:你能尝试一下
coproc
方法吗在发送另一个信号之前尝试
kill-0
不会增加任何安全性。如果在这两种情况下都无法通知进程,则会收到错误消息。唯一增加的是竞争条件(进程可能在
-0
之后但在实际信号之前死亡)。
kill "$pid" >/dev/null 2>&1
strace -f -etrace=execve <program> 2>&1 | 
grep <some_pattern> | ifne <some_script>