进阶Linux:彻底搞懂nohup:原理、用法与实战

1,465 阅读3分钟

日常的后端开发、运维或者服务器管理中,我们经常会看到这样的命令:

nohup npm run start:test > output.log 2>&1 &

很多人知道它能“让进程在后台运行,不会因为关闭终端而中断”,但nohup的原理到底是什么?为什么加个nohup就能让程序一直跑?

本篇:就彻底拆解一下:nohup的底层机制、与其他后台工具的区别,以及如何在实战中正确使用。

🔍 nohup 是什么?

简单理解:

nohup 是一个 Linux/Unix 系统自带的命令,作用是:
忽略终端挂断信号(SIGHUP) ,从而让进程在你关闭终端或者SSH断开后继续运行。 no hang up —— 不挂起、不终止。

Linux 中,如果你关闭终端,系统会给当前终端关联的所有进程发送一个挂起信号(SIGHUP),默认行为是直接终止这些进程。

nohup 会捕获并忽略这个信号,让你的进程不再受终端控制。

⚙️ nohup 的工作原理

操作系统通过信号(signal)来控制进程。 SIGHUP(信号编号1)是一个“终端挂断信号”,当你关闭SSH或退出终端时,系统会向所有该终端下的前台和后台进程发送这个信号。

默认行为是终止进程。

nohup 做了两件事:

1️⃣ 忽略 SIGHUP 信号

内部执行:

signal(SIGHUP, SIG_IGN);

→ 意思是:遇到SIGHUP,不要退出。

2️⃣ 重定向输入输出

  • 如果用户没有指定重定向:
文件描述符默认行为
stdin/dev/null
stdoutnohup.out
stderrnohup.out

避免因为终端关闭,导致输入输出设备消失,从而报错。

是否后台运行? ❌ nohup本身并不负责后台运行。 ✔️ 你需要额外加 &,把它放到后台。

例如:

nohup node app.js &

🧠 nohup 与其他后台工具的区别

工具脱离终端后台运行功能特点
nohup✔️✔️ (配&)忽略SIGHUP,简单可靠
&✔️后台运行,但终端关闭会退出
disown✔️✔️移除job和终端的关联
setsid✔️✔️创建新会话,完全脱离终端
screen✔️✔️虚拟终端,支持断开重连
tmux✔️✔️更现代的screen,支持多窗口
pm2✔️✔️生产级进程管理,支持守护

实战示例

nohup 最常用写法

nohup npm run start:test > output.log 2>&1 &

含义:

  • nohup:忽略SIGHUP
  • npm run start:test:要执行的命令
  • > output.log:标准输出到日志
  • 2>&1:错误输出也一起写到日志
  • &:后台运行

查看日志:

tail -f output.log

更优雅组合:避免nohup.out乱生成,可以这样:

nohup npm run start:test > ./logs/run.log 2>&1 &

或者搭配 disown

nohup npm run start:test > output.log 2>&1 &
disown

⚠️ nohup 的局限

  • 无法监控进程状态。
  • 程序崩溃不会自动重启。
  • 日志需要手动管理(无限增长)。

👉 所以它适合一次性任务、临时性后台运行,不推荐生产环境长期使用。


🚩 更高级的替代方案

🔥 使用 pm2

npm install -g pm2
pm2 start npm --name "test-app" -- run start:test

查看状态:

pm2 list

设置开机自启:

pm2 startup
pm2 save

日志查看:

pm2 logs test-app

🔥 使用 tmuxscreen

tmux new -s test-app
npm run start:test

分离:

Ctrl + B 然后 D

重连:

tmux attach -t test-app

🎯 总结一句话

image.png

nohup = 忽略SIGHUP + 自动重定向IO + 配合 & 后台运行
它是Linux下最简单的“临时后台持久化”工具。

适用场景:

  • ✔️ 临时任务
  • ✔️ 测试脚本
  • ✔️ 短期内不需要崩溃守护的应用

不适用场景:

  • ❌ 生产环境长期服务 → 建议用 pm2systemd 或容器(Docker)。

OK,以上便是本次分享~

欢迎加我:atar24,进技术群、交盆友,我会第一时间通过