nohup命令 #
nohup
命令(no hang up)用于运行命令,使其忽略挂起(SIGHUP)信号。这使得命令可以在用户注销后继续运行,常用于在后台运行长时间执行的任务。
语法 #
nohup 命令 [参数...] [&]
常用选项 #
nohup
命令本身没有太多选项,但通常与其他命令和操作符结合使用:
符号 | 描述 |
---|---|
& |
将命令放在后台运行 |
> 文件 |
将标准输出重定向到文件 |
2> 文件 |
将标准错误重定向到文件 |
2>&1 |
将标准错误重定向到标准输出 |
--help |
显示帮助信息 |
--version |
显示版本信息 |
工作原理 #
当用户注销(登出)系统时,系统会向该用户的所有进程发送SIGHUP(挂起)信号。默认情况下,进程接收到SIGHUP信号后会终止。nohup
命令使进程忽略SIGHUP信号,从而允许进程在用户注销后继续运行。
默认情况下,nohup
命令会将输出重定向到nohup.out
文件,除非标准输出被重定向到其他位置。
常见用法 #
1. 在后台运行命令并忽略挂起信号 #
nohup command &
这会在后台运行命令,并将输出保存到nohup.out
文件。
2. 将输出重定向到特定文件 #
nohup command > output.log 2>&1 &
这会在后台运行命令,将标准输出和标准错误都重定向到output.log
文件。
3. 将标准输出和标准错误分别重定向 #
nohup command > output.log 2> error.log &
4. 丢弃所有输出 #
nohup command > /dev/null 2>&1 &
5. 运行脚本并忽略挂起信号 #
nohup ./script.sh &
6. 查看nohup进程的PID #
nohup command &
echo $!
$!
变量包含最近一个后台进程的PID。
7. 使用特定的nice值运行命令 #
nohup nice -n 19 command &
这会以最低优先级运行命令。
与其他命令结合使用 #
1. 结合time命令测量长时间运行的命令 #
nohup time long_running_command > output.log 2>&1 &
2. 在特定时间运行命令 #
nohup bash -c "sleep 3600 && command" &
这会在1小时后运行命令。
3. 使用at命令在特定时间运行 #
echo "nohup command > output.log 2>&1" | at 2am
4. 使用screen或tmux代替nohup #
screen -dm bash -c "command; echo 'Command completed'"
或
tmux new-session -d "command; echo 'Command completed'"
实用示例 #
1. 运行长时间的数据处理任务 #
nohup python3 data_processing.py > processing.log 2>&1 &
2. 在后台运行服务器 #
nohup ./server --port 8080 > server.log 2>&1 &
3. 运行备份脚本 #
nohup bash backup.sh > backup.log 2>&1 &
4. 运行数据库导出 #
nohup mysqldump -u user -p database > dump.sql 2> dump.err &
5. 下载大文件 #
nohup wget -c https://example.com/large_file.iso &
6. 运行耗时的编译任务 #
nohup make -j4 > build.log 2>&1 &
7. 运行多个命令 #
nohup bash -c "command1 && command2 && command3" > output.log 2>&1 &
查看和管理nohup进程 #
1. 查看nohup进程 #
ps -ef | grep nohup
或
jobs -l
2. 终止nohup进程 #
kill PID
3. 查看nohup.out文件 #
tail -f nohup.out
4. 检查进程是否仍在运行 #
ps -p PID
替代方案 #
除了nohup
命令外,还有其他方法可以使进程在用户注销后继续运行:
-
screen命令:创建可分离的终端会话
screen -S session_name # 运行命令 # 按Ctrl+A, 然后按D分离会话 # 使用screen -r session_name重新连接
-
tmux命令:终端复用器
tmux new -s session_name # 运行命令 # 按Ctrl+B, 然后按D分离会话 # 使用tmux attach -t session_name重新连接
-
disown命令:从当前shell的作业表中移除作业
command & disown %1
-
systemd服务:创建用户级服务
# 创建~/.config/systemd/user/myservice.service文件 systemctl --user start myservice
注意事项 #
-
nohup
命令不会自动将进程放在后台运行,需要使用&
操作符。 -
如果不重定向输出,
nohup
会将输出保存到当前目录下的nohup.out
文件。如果当前目录不可写,则保存到$HOME/nohup.out
。 -
nohup
命令只能忽略SIGHUP信号,不能忽略其他信号(如SIGTERM或SIGKILL)。 -
使用
nohup
运行的进程仍然与终端的标准输入关联,除非明确重定向。 -
在某些系统上,即使不使用
nohup
,通过&
放在后台的进程也可能不会收到SIGHUP信号。
提示 #
- 总是重定向
nohup
命令的输出,以便稍后查看结果或错误 - 记录
nohup
进程的PID,以便稍后可以检查其状态或终止它 - 对于更复杂的需求,考虑使用
screen
或tmux
等工具 - 使用
nohup
运行的进程仍然会在系统重启后终止,如果需要在系统重启后自动启动,应该使用系统的初始化系统(如systemd) - 在脚本中使用
nohup
时,考虑使用完整路径指定命令和输出文件 - 对于需要交互的命令,
nohup
可能不是最佳选择,因为它会与终端分离 - 使用
nohup
运行的进程仍然会在父进程终止时收到SIGHUP信号,除非它已经成为孤儿进程并被init进程收养