You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

含nohup的Linux脚本无法终止,求正确编写方式

问题描述

我有一个Linux脚本(script.sh):

#!/bin/bash
echo "Script started"
nohup python3 run_process.py > /dev/null 2>&1 &
echo "Script finished"

这个脚本能正常启动后台进程run_process.py,但脚本自身始终处于运行状态(可通过ps x命令查看)。试过disown、setsid等方案都无效。

完整的脚本原型如下,用于终止后台进程、执行更新、重启进程:

#!/bin/bash
echo "Script started"
pkill -f process_1.py
sleep 1
cd /to_some_file && python3 program_1.py
sleep 1
cd /to_some_file/ && nohup python3 run_process_1.py > /dev/null 2>&1 &
sleep 1
pkill -f process_2.py
sleep 1
cd /to_some_file && python3 program_2.py
sleep 1
cd /to_some_file/ && nohup python3 run_process_2.py > /dev/null 2>&1 &
echo "Script finished"
exit 0

请问怎么编写包含nohup的.sh脚本,让它执行完成后能正确终止?

解决方案

脚本无法正常终止的核心原因是**nohup启动的进程可能仍占用脚本的标准输入/输出/错误流**,或未完全脱离当前会话关联。以下两种方法可解决问题:

方法1:彻底隔离进程IO流与会话

在nohup命令前添加setsid,同时将标准输入重定向到空设备,让进程完全脱离当前脚本的终端控制:

setsid nohup python3 run_process_1.py > /dev/null 2>&1 < /dev/null &
  • setsid:让进程在新会话组运行,切断与当前脚本的终端关联
  • < /dev/null:避免进程等待输入导致脚本挂起

方法2:后台启动后立即disown

若setsid无效,可在后台启动进程后,用disown将其从当前shell作业列表移除,脚本即可正常退出:

nohup python3 run_process_1.py > /dev/null 2>&1 &
disown $!
  • $!:指代刚启动的后台进程PID,disown会解除当前shell对该进程的管理

完整修改后的脚本

结合方法1,修改后的脚本如下:

#!/bin/bash
echo "Script started"

pkill -f process_1.py
sleep 1
cd /to_some_file && python3 program_1.py
sleep 1
cd /to_some_file/ && setsid nohup python3 run_process_1.py > /dev/null 2>&1 < /dev/null &
sleep 1

pkill -f process_2.py
sleep 1
cd /to_some_file && python3 program_2.py
sleep 1
cd /to_some_file/ && setsid nohup python3 run_process_2.py > /dev/null 2>&1 < /dev/null &

echo "Script finished"
exit 0

另外需注意:检查program_1.py和program_2.py是否残留未终止的子进程,这类进程也可能导致脚本无法退出,需确保它们运行后完全结束。

内容的提问来源于stack exchange,提问作者student_1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:36:04