我有 script.sh,所以我想通过终端 (./script.sh) 运行它
如果我运行 script.sh 那么它应该根据某些条件启动一些其他命令(在这种情况下为 ffmpeg)
它是这样工作的,但问题是:如果我停止/杀死 script.sh 那么 ffmpeg 也会被杀死/停止
我认为 ffmpeg 命令或其他命令不需要依赖于 script.sh,即使我关闭它也应该运行
#!/bin/bash
while xxxxxxx; do
startFFMPEG() {
nohup $(/root/bin/ffmpeg -i "url" -i "/var/www/logo/logo.png" outputcmd -y "1.m3u8" </dev/null >/dev/null 2>&1 || /root/bin/ffmpeg -i "url" -i "/var/www/logo/logo.png" outputcmd -y "2.m3u8" </dev/null >/dev/null 2>&1 || /root/bin/ffmpeg -i "url" -i "/var/www/logo/logo.png" outputcmd -y "3.m3u8" </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 &
}
echo "RUN COMMAND1"
startFFMPEG &
startFFMPEG() {
nohup $(/root/bin/ffmpeg -i "url2" -i "/var/www/logo/logo.png" outputcmd -y "11.m3u8" </dev/null >/dev/null 2>&1 || /root/bin/ffmpeg -i "url2" -i "/var/www/logo/logo.png" outputcmd -y "12.m3u8" </dev/null >/dev/null 2>&1 || /root/bin/ffmpeg -i "url3" -i "/var/www/logo/logo.png" outputcmd -y "13.m3u8" </dev/null >/dev/null 2>&1 ) >/dev/null 2>&1 &
}
echo "RUN COMMAND 2"
startFFMPEG &
sleep 10
done
我该怎么做才能解决这个问题,这样即使脚本被杀死,ffmpeg 也会运行
答案 0 :(得分:1)
这里没有理由使用 nohup
-- 没有任何理由。
nohup
只做四件事:
/dev/null
重定向标准输入(如果之前来自 TTY)nohup.out
(如果之前转到 TTTY)nohup.out
(如果之前转到 TTY)disown -h
来强制执行该行为)。这些就是确保封闭终端不会以与 nohup
提供的相同级别的效率接收子进程的全部内容。 (如果您希望 ctrl+c 受到保护,您可以另外要求 setsid
或明确处理 SIGINT)。
你可以自己做这一切。大多数情况下,你已经自己做了。
#!/bin/bash
trap : HUP # Tell the shell not to do anything when it gets a HUP
startFFMPEG() {
trap '' INT # ignore SIGINT
for ((i=0; i<3; i++)); do
/root/bin/ffmpeg \
-i "url" \
-i "/var/www/logo/logo.png" \
outputcmd \
-y "$((i+1)).m3u8" \
</dev/null >/dev/null 2>&1 \
&& return
done
}
while xxxxxxx; do
echo "RUN COMMAND1"
startFFMPEG &
echo "RUN COMMAND 2"
startFFMPEG &
sleep 10
done
答案 1 :(得分:1)
当您 kill
(3posix) 父进程 (script.sh) 时,它显然会停止执行新命令。任何子进程,如子 shell $()
和 ffmpeg
进程都将继续运行。
如果您使用 ctrl-c 中断父进程,那么 SIGINT 将发送到进程 group,这也将终止子进程。解决这个问题的方法是使用 setsid
在新会话中运行子流程:
setsid /root/bin/ffmpeg -i "url" ... &
正如@CharlesDuffy 指出的那样,当孩子们尝试写入连接到父级的管道时,他们通常会得到一个 SIGPIPE。在这种情况下,它们已被重定向到 /dev/null,因此不会发生写入。
答案 2 :(得分:-1)
您可以使用screen软件。
在 ubuntu 上安装:
sudo apt uopdate
sudo apt install screen
然后,在终端中启动屏幕:
screen
返回最新屏幕
screen -r
有关此link的更多信息