如何正确停止 nohup 启动的后台进程
理解 nohup 进程的特性
当使用 nohup command &
启动进程时:
- 忽略挂断信号:进程会忽略
SIGHUP
信号(终端关闭时发送) - 脱离终端控制:即使关闭启动它的终端,进程仍继续运行
- 输出重定向:默认将输出保存到
nohup.out
文件
标准停止方法(推荐)
# 示例输出: # user 12345 0.0 0.1 20250 1024 pts/0 S Jul01 0:00 python app.py # 2. 发送终止信号 kill -15 12345 # 发送SIGTERM信号(优雅终止) # 3. 验证是否终止 ps -p 12345 # 无输出则表示已停止
进阶处理方案
场景1:进程未响应 SIGTERM
kill -9 12345 # 强制终止(SIGKILL信号)
⚠️ 注意:强制终止可能导致数据丢失,仅作为最后手段
场景2:批量终止同名进程
pkill -f "进程名关键词" # 按名称终止 pkill -15 -f "python.*app" # 优雅终止正则匹配的进程
场景3:通过端口查找终止
# 查找占用8080端口的进程 lsof -i :8080 | awk 'NR==2 {print $2}' | xargs kill -15
预防进程残留的技巧
-
使用进程管理工具(推荐):
# 安装screen sudo apt install screen # 创建会话 screen -S mysession # 启动进程后按 Ctrl+A+D 脱离会话 # 恢复会话 screen -r mysession
-
记录PID到文件:
nohup ./server.sh & echo $! > server.pid # 停止时执行 kill -15 $(cat server.pid)
常见问题排查
Q:进程显示为僵尸(Z状态)?
- 原因:父进程未回收子进程
- 解决:重启父进程或重启系统
Q:nohup.out 文件持续增大?
- 定期清理:
cp /dev/null nohup.out # 清空内容不删除文件
最佳实践建议
- 优先使用进程管理器:如 systemd/supervisor
- 避免直接使用 kill -9:可能导致资源未释放
- 日志分割:使用
logrotate
管理输出文件 - 权限最小化:不要用 root 运行 nohup 进程
技术原理说明:
nohup
通过拦截SIGHUP
信号实现进程持久化,但进程仍响应其他信号。SIGTERM
(15)允许进程执行清理操作,而SIGKILL
(9)会立即终止进程且不可被捕获。
引用说明:
本文方法基于 Linux 标准进程管理规范,参考 Linux man-pages 中关于 signal(7)、kill(1)、nohup(1) 的技术文档,并在 CentOS/Ubuntu 等主流发行版验证通过。
原创文章,发布者:酷番叔,转转请注明出处:https://cloud.kd.cn/ask/7632.html