Linux nohup 命令完全指南

前面在 《Linux Systemd 服务注册指南》 一文中介绍了linux上如何注册Systemd 服务,但真到了临时跑个脚本的时候,systemd 反而太重了。这时候就该 nohup 出场。本文从 systemd 引申到 nohup,讲透原理、标准写法、使用场景与常见坑。

一、什么是 nohup

nohup 是 "No Hang Up"(不挂断)的缩写,是 Linux/Unix 系统中用于在后台不挂断运行命令的工具。其核心功能是使进程忽略 SIGHUP(挂断)信号,确保在用户退出登录、关闭终端或 SSH 断开后,进程仍能继续运行。


二、工作原理

1. 信号屏蔽机制

当终端关闭或用户注销时,Shell 会向其所有子进程发送 SIGHUP 信号,导致进程终止。nohup 通过调用 signal(SIGHUP, SIG_IGN) 将进程对 SIGHUP 信号的处理方式设置为忽略,使进程不受终端断开的影响。

2. 输入输出重定向机制

  • 标准输入(stdin,文件描述符 0):默认重定向到 /dev/null,避免进程因等待输入而阻塞。
  • 标准输出(stdout,文件描述符 1):默认重定向到当前目录下的 nohup.out 文件;若当前目录不可写,则重定向到 $HOME/nohup.out。
  • 标准错误(stderr,文件描述符 2):默认合并到标准输出,一并写入 nohup.out 文件。

3. 退出状态码

退出状态 含义
125 nohup 本身执行失败
126 能找到命令但无法调用执行
127 nohup 出错或找不到指定命令
其他 返回所执行命令的退出状态

三、基本语法

nohup COMMAND [ARG...] [> output_file 2>&1] [&]

四、常用参数与选项

参数 说明
& 将命令放入后台执行(nohup 本身不自动后台运行,需配合 & 使用)
> file 重定向标准输出到指定文件
2>&1 将标准错误重定向到标准输出,合并日志
/dev/null 丢弃所有输出,不生成日志文件
-p pid 修改指定已运行进程以忽略 SIGHUP 信号(部分系统如 AIX、Oracle 支持)
-g gpid 对指定进程组执行忽略 SIGHUP 操作
-a 强制更改信号处理,即使进程已安装处理程序
-F 强制抓取目标进程控制权

五、常用执行方式

1. 基础后台运行

nohup command &

2. 自定义日志文件(推荐)

nohup command > output.log 2>&1 &

其中 > output.log 重定向标准输出,2>&1 将标准错误合并至标准输出,& 表示后台执行。

3. 丢弃所有输出

nohup command > /dev/null 2>&1 &

4. 分离输出与错误日志

nohup command > stdout.log 2> stderr.log &

5. 追加模式写入日志

nohup command >> output.log 2>&1 &

6. 运行复杂命令

nohup sh -c 'cd /path/to/dir && command1 && command2' > log.txt 2>&1 &

六、典型应用场景

  • 远程服务器上执行长时间任务:如数据备份、模型训练、编译、数据迁移等。
  • 启动后台服务或守护进程:如 Java 服务、Web 应用、Python 脚本等。
  • 系统维护与自动化脚本执行:如 rsync 数据同步、数据库维护等。

常见示例

# 后台运行 Java 应用
nohup java -jar app.jar > app.log 2>&1 &

# 后台运行 Python 脚本
nohup python3 train.py > train.log 2>&1 &

# 后台运行 Shell 脚本
nohup ./backup.sh > backup.log 2>&1 &

# 后台运行数据同步任务
nohup rsync -av /data /backup > sync.log 2>&1 &

七、进程管理

1. 查看进程

# 查看系统进程
ps -ef | grep "command"
ps aux | grep command
pgrep -a command

# 查看当前会话后台任务(仅当前终端有效)
jobs -l

2. 终止进程

# 优雅终止
kill PID

# 强制终止
kill -9 PID

3. 实时查看日志

tail -f nohup.out
tail -f output.log

八、注意事项

1. nohup 与 & 的关系

  • & 仅将命令放入后台运行,终端关闭后进程会因 SIGHUP 信号而终止。
  • nohup 仅忽略 SIGHUP 信号,默认在前台运行,会阻塞终端。
  • 两者结合(nohup command &)才是生产环境最常用的组合:后台运行 + 防挂断。

2. 日志管理

  • 默认的 nohup.out 文件可能无限增长,需定期清理或使用 logrotate 进行日志轮转,防止磁盘占满。
  • 推荐显式指定输出文件路径,便于日志管理。
  • 不要直接 rm 删除正在写入的 nohup.out,可能导致进程无法继续写入日志。正确做法是使用 > nohup.out 清空文件内容。

3. 权限问题

  • 确保日志输出目录具有写入权限,否则命令可能执行失败。
  • 确保对目标程序有执行权限。

4. 工作目录问题

  • 若脚本中使用相对路径,需在脚本所在目录执行 nohup,或改用绝对路径。
  • 指定工作目录的方式:
cd /path/to/dir && nohup command > log.txt 2>&1 &

5. 输出缓冲问题

  • Python 等语言存在输出缓冲,需加 -u 参数实现实时日志:
nohup python -u script.py > output.log 2>&1 &

6. 信号免疫范围

  • nohup 仅忽略 SIGHUP 信号,不免疫 SIGTERM、SIGKILL 等其他终止信号。

九、替代方案对比

特性 nohup screen/tmux systemd
核心功能 忽略 SIGHUP 信号 创建持久化虚拟终端会话 系统级服务管理
交互性 无,启动后无法再交互 有,可随时重连会话 无
开机自启 不支持 不支持 支持
崩溃重启 不支持 不支持 支持
日志管理 手动管理 手动管理 统一日志管理(journalctl)
易用性 非常简单,一条命令 中等,需学习基本命令 较复杂,需编写服务文件
适用场景 一次性、无需交互的长期任务 需要调试、交互、多任务管理 生产环境关键服务

简单选择建议

  • 跑一个脚本,不需要再管它:用 nohup 最快捷。
  • 需要随时查看进度、进行调试:用 screen 或 tmux。
  • 生产环境关键服务:推荐使用 systemd 管理。

十、补充:disown 与 setsid

disown 命令

如果已经启动了一个后台进程(使用 &),可以使用 disown 将其从当前 Shell 会话的作业表中移除,使其不受终端关闭的影响:

command &
disown %1

setsid 命令

setsid 会创建一个新的会话组,使进程不再与任何终端关联,实现彻底脱离终端:

setsid nohup command [args] &

总结

nohup 是 Linux 系统中最简单直接的后台持久运行工具。核心用法一句话概括:想跑不怕关终端,就在命令前面加个 nohup,后面加个 &。

推荐的标准写法:

nohup command > output.log 2>&1 &
posted @ 2026-10-16 09:08  EXIORAN  阅读(22)  评论(0)    收藏  举报