linux shell 脚本:在后台运行多个命令,即使脚本结束也不会终止

时间:2021-03-27 17:39:51

标签: linux bash shell nohup

我有 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 也会运行

3 个答案:

答案 0 :(得分:1)

这里没有理由使用 nohup -- 没有任何理由。

nohup 只做四件事:

  1. /dev/null 重定向标准输入(如果之前来自 TTY)
  2. 将标准输出重定向到 nohup.out(如果之前转到 TTTY)
  3. 将 stderr 重定向到 nohup.out(如果之前转到 TTY)
  4. 忽略收到的任何 HUP(“挂断”)信号。 (默认情况下,shell 已经在非交互式脚本中忽略 HUP,甚至在交互式解释器中,也可以使用 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的更多信息