在Linux系统中执行耗时较长的任务时,比如运行数据备份脚本、启动长期运行的服务程序,我们经常会遇到一个问题:一旦关闭当前登录的终端,正在运行的程序就会跟着终止。这是因为默认情况下,终端启动的进程会收到终端挂断信号,而nohup命令就是用来解决这个问题的工具。

nohup是什么
nohup是no hang up的缩写,意思是“不挂断”,它是Linux系统自带的命令行工具,主要作用是让后续的命令忽略终端的挂断信号(SIGHUP)。当我们用nohup启动程序时,即使关闭当前终端、退出登录,程序也不会收到挂断信号,会持续在后台运行,直到任务完成或者手动终止进程。
nohup基本语法
nohup的基础使用语法非常简单,基本格式如下:
# 基础语法 nohup 要执行的命令 [参数] & # 示例:用nohup后台运行一个循环打印的脚本 nohup bash test.sh &
这里的&符号是把命令放到后台执行,和nohup搭配使用才能让程序既后台运行又不随终端关闭而终止。如果不加&,程序会在前台运行,虽然不会随终端关闭终止,但会占用当前终端,无法执行其他操作。
nohup输出处理
默认情况下,nohup会把程序的输出写到当前目录下的nohup.out文件中,如果当前目录没有写入权限,就会写到用户家目录的nohup.out里。如果我们不想用默认的输出文件,也可以手动指定输出位置:
# 把标准输出和标准错误都重定向到指定文件 nohup bash test.sh > my.log 2>&1 & # 解释: # > my.log 表示把标准输出写到my.log # 2>&1 表示把标准错误也重定向到标准输出的位置,也就是my.log # 最后的&是后台运行
如果程序不需要输出任何内容,也可以把输出重定向到空设备:
# 丢弃所有输出 nohup bash test.sh > /dev/null 2>&1 &
如何管理nohup运行的进程
用nohup启动程序后,我们可以通过以下几种方式查看和管理对应的进程:
- 用
jobs命令查看当前终端的后台任务,不过如果已经退出过终端再重新登录,这个命令就看不到之前的nohup任务了 - 用
ps命令配合grep查找进程:ps -ef | grep 程序名,可以找到对应的进程ID(PID) - 用
kill命令终止进程:kill -9 PID,这里的PID是之前查到的进程ID
常见使用场景示例
下面是几个nohup的常见使用场景,方便大家参考:
场景1:后台运行Python脚本
# 后台运行Python脚本,输出写到script.log nohup python3 main.py > script.log 2>&1 &
场景2:启动Java服务
# 后台启动Java jar包,输出写到service.log nohup java -jar app.jar > service.log 2>&1 &
场景3:执行长时间运行的Shell脚本
# 后台执行备份脚本,不记录输出 nohup bash backup.sh > /dev/null 2>&1 &
注意事项
使用nohup的时候需要注意几个点:
- nohup只能忽略终端挂断信号,如果程序本身有bug崩溃,或者系统重启,程序还是会停止运行
- 如果程序需要交互输入,不适合用nohup后台运行,因为后台运行无法接收终端的输入
- 长期运行的程序要定期清理输出日志,避免
nohup.out或者自定义日志文件过大占用磁盘空间 - 如果是在脚本中使用nohup,要确保命令的语法正确,尤其是重定向的部分,避免输出异常
掌握nohup的使用方法,能帮我们在Linux系统中更灵活地管理长时间运行的任务,避免因为终端关闭导致任务中断,是Linux运维和开发中非常实用的基础技能。