输出包含指定字符串后执行bash命令

Execute bash command after a specified string is contained in output

我正在尝试 运行 这个命令:

~ $ sudo ffmpeg -stream_loop -1 -re -i funnyVideo.mp4 -map 0:v -f v4l2 /dev/video2

每秒输出它显示的帧数:

... other ...
frame=    1 fps=0.0 q=-0.0 size=N/A time=00:00:00.03 bitrate=N/A speed=0.0665x

然后最后一行被替换为新显示的帧数。

frame=   23 fps= 23 q=-0.0 size=N/A time=00:00:00.76 bitrate=N/A dup=15 drop=0

等等。我正在尝试等待字符串“frame= 205”,执行另一个脚本并让进程继续:

while IFS= read -r line; do
    if [[ "$line" =~ "frame=   205" ]]; then
          echo "Frame 205 has been reached"
          break;
    fi
done < <(sudo ffmpeg -stream_loop -1 -re -i funnyVideo.mp4 -map 0:v -f v4l2 /dev/video2)

我不知道这里发生了什么。为什么 echoing Frame 205 has been reached 即使我可以在一段时间后看到包含文本 frame= 205 的行?

你能看到它就是问题所在。你永远不会输出你阅读的行,所以它们是如何出现的?因为没有被抓到。

要捕获此类行,请使用 <(sudo ffmpeg ... 2>&1)

将 stderr 重定向到 stdout

然后你会发现 ffmpeg 在这些更新之间没有输出 \ns,这就是它如何使行更新到位。您可以使用 IFS= read -d $'\r' -r line 来读取回车 returns 分隔符。

PS:帧数基于计时器,因此不确定。有时它会给你 frame= 205 有时 frame= 209.