Linux 后台任务详解:、nohup、jobs、systemd 的区别
Linux 后台任务详解:&、nohup、jobs、systemd 的区别
1. 前言
在 Linux 中,我们经常需要让程序在后台运行。
常见场景:
- 后台执行脚本;
- 退出 SSH 后程序继续运行;
- 让服务开机自启;
- 查看后台任务;
- 把程序做成系统服务。
常见工具有:
&nohupjobsfgbgsystemd本文重点讲清楚它们的区别和使用场景。
2. 前台任务和后台任务
默认运行命令时,任务在前台执行。
sleep100此时终端会被占用。
命令结束前,不能继续输入其他命令。
如果想后台执行,在命令后加&:
sleep100&输出类似:
[1] 12345含义:
| 内容 | 含义 |
|---|---|
[1] | 当前 shell 中的任务编号 |
12345 | 进程 PID |
3. jobs:查看当前 shell 的后台任务
查看后台任务:
jobs示例:
[1]+ Runningsleep100&注意:
jobs 只能查看当前 shell 管理的任务。如果重新打开一个终端,原来终端里的 jobs 不会显示在新终端中。
4. fg 和 bg
把后台任务切回前台:
fg%1暂停前台任务:
Ctrl+Z暂停后查看:
jobs可能看到:
[1]+ Stopped python app.py让暂停任务继续在后台运行:
bg%1这一套适合临时控制任务。
5. & 的局限
使用:
python app.py&程序会进入后台。
但是如果关闭终端,程序可能退出。
原因是它仍然和当前终端会话有关。
终端关闭时,系统可能向进程发送SIGHUP信号。
所以:
& 适合临时后台运行,不适合长期服务。6. nohup:退出终端后继续运行
nohup的作用是让程序忽略挂起信号。
常见写法:
nohuppython app.py>app.log2>&1&拆开理解:
| 部分 | 含义 |
|---|---|
nohup | 忽略 SIGHUP |
python app.py | 要运行的程序 |
> app.log | 标准输出写入日志 |
2>&1 | 标准错误也写入日志 |
& | 后台运行 |
查看日志:
tail-fapp.log如果不指定日志文件,默认可能写入:
nohup.out7. 2>&1 是什么
Linux 中有三个常见文件描述符:
| 编号 | 含义 |
|---|---|
| 0 | 标准输入 |
| 1 | 标准输出 |
| 2 | 标准错误 |
命令:
>app.log等价于:
1>app.log只重定向标准输出。
如果还想把错误输出也写进同一个文件:
>app.log2>&1所以完整后台运行常写成:
nohupcommand>app.log2>&1&8. disown:脱离当前 shell
如果已经用&启动任务:
python app.py&可以用:
jobsdisown %1让任务脱离当前 shell 作业管理。
但实际项目中,更建议直接用nohup或systemd。
9. systemd:正式服务管理
systemd是现代 Linux 常用的系统服务管理器。
它适合管理长期运行的服务。
常见命令:
systemctl start nginx systemctl stop nginx systemctl restart nginx systemctl status nginx systemctlenablenginx systemctl disable nginx| 命令 | 作用 |
|---|---|
| start | 启动 |
| stop | 停止 |
| restart | 重启 |
| status | 查看状态 |
| enable | 开机自启 |
| disable | 取消开机自启 |
10. 创建 systemd 服务
假设程序路径:
/opt/myapp/app创建服务文件:
sudovim/etc/systemd/system/myapp.service内容:
[Unit] Description=My App Service After=network.target [Service] Type=simple WorkingDirectory=/opt/myapp ExecStart=/opt/myapp/app Restart=always RestartSec=3 User=www-data Group=www-data [Install] WantedBy=multi-user.target重新加载配置:
sudosystemctl daemon-reload启动服务:
sudosystemctl start myapp查看状态:
sudosystemctl status myapp设置开机自启:
sudosystemctlenablemyapp查看日志:
journalctl-umyapp-f11. &、nohup、systemd 对比
| 方式 | 适合场景 | 退出终端是否稳定 | 是否支持开机自启 | 是否方便管理 |
|---|---|---|---|---|
& | 临时后台任务 | 不稳定 | 不支持 | 一般 |
nohup + & | 长时间脚本 | 较稳定 | 不支持 | 一般 |
tmux/screen | 交互式会话 | 稳定 | 不支持 | 适合调试 |
systemd | 正式服务 | 稳定 | 支持 | 很方便 |
选择建议:
临时跑一下:& 退出终端继续跑:nohup 需要交互会话:tmux/screen 正式服务部署:systemd12. 常见问题
12.1 nohup 启动后马上退出
先看日志:
catapp.logcatnohup.out常见原因:
- 工作目录不对;
- 配置文件路径错误;
- 端口被占用;
- 环境变量缺失;
- 程序启动时报错。
12.2 systemd 手动运行正常,服务运行失败
常见原因是 systemd 环境变量较少,不会自动加载用户的.bashrc。
解决思路:
- 使用绝对路径;
- 配置
WorkingDirectory; - 配置
Environment; - 指定正确
User; - 用
journalctl -u 服务名看日志。
示例:
Environment=JAVA_HOME=/usr/lib/jvm/java-17 Environment=PATH=/usr/local/bin:/usr/bin:/bin13. 小结
Linux 后台任务可以这样记:
&:放到当前 shell 后台 jobs:看当前 shell 的任务 fg/bg:前后台切换 nohup:退出终端继续运行 systemd:正式服务管理常用命令:
command&jobsfg%1bg%1nohupcommand>app.log2>&1&systemctl status myapp journalctl-umyapp-f如果只是临时执行脚本,用nohup就够。
如果是线上服务,建议写成 systemd 服务。
