我正在处理一个脚本,该脚本需要检测程序中对FFMPEG的首次调用,并从那时开始运行脚本。
核心代码如下:
strace -f -etrace=execve <program> 2>&1 | grep <some_pattern> | <run_some_script>
所需的行为是,当第一个 grep 结果出来时,脚本应启动。并且,如果<program>
终止之前没有匹配的内容,则应忽略该脚本。
主要问题是如何根据grep的输出有条件地执行脚本,以及在程序终止后如何终止脚本。
我认为可以使用 read 解决第一个问题,因为使用 grep 文本作为信号,因此其内容无关紧要:
... | read -N 1 && <run_some_script>
第二个可以使用折断管道机制解决:
<run_some_script> > >(...)
但是我不知道如何使它们一起工作。还是有更好的解决方案?
答案 0 :(得分:2)
您可以要求grep
仅匹配一次模式,然后返回并使其返回成功错误代码。将这些放在一起(如果有条件的话)
if strace -f -etrace=execve <program> 2>&1 | grep -q <some_pattern>; then
echo 'run a program'
fi
-q
标志用于禁止显示由grep
命令返回的通常标准输出内容,正如您提到的那样,您只想使用grep
结果执行操作而不使用结果。
或者您可能需要使用coproc
运行命令以在后台运行,并检查产生的输出的每一行。只需为要运行的命令编写包装器,如下所示。 单个命令不需要该功能,但是对于多个命令,该功能将更为重要。
wrapper() { strace -f -etrace=execve <program> 2>&1 ; }
使用coproc
类似于在后台运行命令,但是提供了一种捕获命令运行输出的简单方法
coproc outputfd { wrapper; }
现在,通过读取wrapper
提供的文件描述符,观察coproc
内部运行的命令的输出。下面的代码将监视输出,并在pattern
的第一个匹配项上启动它,以启动运行该命令的后台作业,并将进程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
答案 1 :(得分:0)
使用ifne
util:
strace -f -etrace=execve <program> 2>&1 |
grep <some_pattern> | ifne <some_script>