安全地杀死在 bash 脚本中启动的后台进程

Posted

技术标签:

【中文标题】安全地杀死在 bash 脚本中启动的后台进程【英文标题】:Safely kill background process started in bash script 【发布时间】:2021-08-12 22:30:55 【问题描述】:

假设我在 bash 脚本中启动了一个后台进程,在本例中为 http-server,我想在脚本退出时终止它。我可能会这样做:

# launch http-server in the background
http-server -p8080 &

# capture PID of background process
HTTP_PID=$!

trap "kill $HTTP_PID" EXIT 

# ... more stuff 

这似乎是捕获后台进程的PID的推荐方式,但是有一个问题:如果进程无法启动或稍后在任何时候失败,PID可能会被另一个进程回收并使用,其中如果我的kill 会杀死系统上的一些随机进程。

我怎样才能安全地杀死在此脚本中启动的进程,如果该进程已经死亡则什么都不做?

【问题讨论】:

【参考方案1】:

这应该达到你的预期:

trap "pkill --parent $$ http-server" EXIT

杀死一个特定的pid:

function killpid 
    local ppid=$1 pid=$2 cmd=$3
    local v_pid="$(ps -h --ppid $ppid -o pid,cmd | awk -v pid=$pid -v cmd="$cmd" '$1 == pid && $2 == cmd print pid')"
    if  test -n "$v_pid"; then
        echo "Killing $v_pid..."
        kill $v_pid
    fi


sleep 2 &
echo "Spawning $!"
sleep 2 &
echo "Spawning $!"
trap "killpid $$ $! sleep" EXIT

测试后用http-server 替换sleep

【讨论】:

嗯,不错的方法。使用--exact 可能会更安全一些。很遗憾,pkill 没有 --pid 选项,因为这不允许我针对我启动的http-server特定 实例,尽管在这种情况下我只启动一个. ‘ps’同时具有-pid和-ppid,当你真正杀死一个特定的进程id时,你应该能够验证它们

以上是关于安全地杀死在 bash 脚本中启动的后台进程的主要内容,如果未能解决你的问题,请参考以下文章

PHP启动的Bash后台进程不起作用

Bash - 启动和终止进程

脚本退出后执行后台进程

如果我们关闭它启动的终端,linux 会杀死后台进程吗?

shell脚本让进程在后台运行以及进程后台转前台

在启动时保持 bash 脚本在后台循环的最佳方法是啥 - Linux?