含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
相关产品推荐
相关产品推荐

