![bash:让进程在后台运行,如果需要则重新启动,但从父脚本接收 CTRL-C](https://linux22.com/image/1506596/bash%EF%BC%9A%E8%AE%A9%E8%BF%9B%E7%A8%8B%E5%9C%A8%E5%90%8E%E5%8F%B0%E8%BF%90%E8%A1%8C%EF%BC%8C%E5%A6%82%E6%9E%9C%E9%9C%80%E8%A6%81%E5%88%99%E9%87%8D%E6%96%B0%E5%90%AF%E5%8A%A8%EF%BC%8C%E4%BD%86%E4%BB%8E%E7%88%B6%E8%84%9A%E6%9C%AC%E6%8E%A5%E6%94%B6%20CTRL-C.png)
我正在使用livestreamer
并ffmpeg
以 0.1 fps 的速度从实时流中抓取图像:
livestreamer --player "ffmpeg -i" --player-args "{filename} -vf fps=1/10 out%04d.png" https://www.ustream.tv/channel/number worst
我无法让 ffmpeg 覆盖其输出,因此它会不断使用该out%04d.png
模式创建新文件。这很好,我可以跟踪最新的输出文件并删除旧文件。但是,该livestreamer
进程有时会因各种原因退出,只要我希望它运行,我就想自动重新启动它。
尝试使用子 shell 并没有像我预期的那样对 CTRL-C 做出反应,因为信号没有在子 shell 上传递:
#!/bin/bash
( while true; do
livestreamer --player "ffmpeg -i" --player-args "{filename} -vf fps=0.1 out%04d.png" https://www.ustream.tv/channel/number worst
done ) &
while true; do
newestImage=${code to find newest image}
postProcess $newestImage
deleteOldImages
sleep 5
done
当我发送SIGINT
上述脚本时,即使我关闭启动父脚本的 shell,子 shell 仍然处于活动状态。输出目录中充满了新文件,而原本应该删除它们的代码却不再运行。Atrap
也无济于事:
trap "kill $SUBSHELL_PID" SIGINT
( ... ) & # subshell as above
SUBSHELL_PID=&!
这样我甚至无法中断父脚本。显然,我对 bash 中的信号处理毫无经验,因此我很高兴收到任何能帮助我前进的建议。只要父脚本正在运行,我就需要重新启动帧抓取器,并跟踪旧文件以将其删除。
编辑:首先,子 shell 是不是一个坏主意?我是否可以以某种方式livestreamer
在后台启动并在需要时将其终止,或者在其自行退出时重新启动它?
答案1
杀死直播主本身。
trap "killall livestreamer" SIGINT