Linux 后台任务详解:&、nohup、jobs、systemd 的区别

Linux 后台任务详解:&、nohup、jobs、systemd 的区别

1. 前言

在 Linux 中,我们经常需要让程序在后台运行。

常见场景:

  • 后台执行脚本;
  • 退出 SSH 后程序继续运行;
  • 让服务开机自启;
  • 查看后台任务;
  • 把程序做成系统服务。

常见工具有:

bash 复制代码
&
nohup
jobs
fg
bg
systemd

本文重点讲清楚它们的区别和使用场景。


2. 前台任务和后台任务

默认运行命令时,任务在前台执行。

bash 复制代码
sleep 100

此时终端会被占用。

命令结束前,不能继续输入其他命令。

如果想后台执行,在命令后加 &

bash 复制代码
sleep 100 &

输出类似:

text 复制代码
[1] 12345

含义:

内容 含义
[1] 当前 shell 中的任务编号
12345 进程 PID

3. jobs:查看当前 shell 的后台任务

查看后台任务:

bash 复制代码
jobs

示例:

bash 复制代码
[1]+  Running    sleep 100 &

注意:

text 复制代码
jobs 只能查看当前 shell 管理的任务。

如果重新打开一个终端,原来终端里的 jobs 不会显示在新终端中。


4. fg 和 bg

把后台任务切回前台:

bash 复制代码
fg %1

暂停前台任务:

text 复制代码
Ctrl+Z

暂停后查看:

bash 复制代码
jobs

可能看到:

bash 复制代码
[1]+  Stopped    python app.py

让暂停任务继续在后台运行:

bash 复制代码
bg %1

这一套适合临时控制任务。


5. & 的局限

使用:

bash 复制代码
python app.py &

程序会进入后台。

但是如果关闭终端,程序可能退出。

原因是它仍然和当前终端会话有关。

终端关闭时,系统可能向进程发送 SIGHUP 信号。

所以:

text 复制代码
& 适合临时后台运行,不适合长期服务。

6. nohup:退出终端后继续运行

nohup 的作用是让程序忽略挂起信号。

常见写法:

bash 复制代码
nohup python app.py > app.log 2>&1 &

拆开理解:

部分 含义
nohup 忽略 SIGHUP
python app.py 要运行的程序
> app.log 标准输出写入日志
2>&1 标准错误也写入日志
& 后台运行

查看日志:

bash 复制代码
tail -f app.log

如果不指定日志文件,默认可能写入:

bash 复制代码
nohup.out

7. 2>&1 是什么

Linux 中有三个常见文件描述符:

编号 含义
0 标准输入
1 标准输出
2 标准错误

命令:

bash 复制代码
> app.log

等价于:

bash 复制代码
1> app.log

只重定向标准输出。

如果还想把错误输出也写进同一个文件:

bash 复制代码
> app.log 2>&1

所以完整后台运行常写成:

bash 复制代码
nohup command > app.log 2>&1 &

8. disown:脱离当前 shell

如果已经用 & 启动任务:

bash 复制代码
python app.py &

可以用:

bash 复制代码
jobs
disown %1

让任务脱离当前 shell 作业管理。

但实际项目中,更建议直接用 nohupsystemd


9. systemd:正式服务管理

systemd 是现代 Linux 常用的系统服务管理器。

它适合管理长期运行的服务。

常见命令:

bash 复制代码
systemctl start nginx
systemctl stop nginx
systemctl restart nginx
systemctl status nginx
systemctl enable nginx
systemctl disable nginx
命令 作用
start 启动
stop 停止
restart 重启
status 查看状态
enable 开机自启
disable 取消开机自启

10. 创建 systemd 服务

假设程序路径:

bash 复制代码
/opt/myapp/app

创建服务文件:

bash 复制代码
sudo vim /etc/systemd/system/myapp.service

内容:

ini 复制代码
[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

重新加载配置:

bash 复制代码
sudo systemctl daemon-reload

启动服务:

bash 复制代码
sudo systemctl start myapp

查看状态:

bash 复制代码
sudo systemctl status myapp

设置开机自启:

bash 复制代码
sudo systemctl enable myapp

查看日志:

bash 复制代码
journalctl -u myapp -f

11. &、nohup、systemd 对比

方式 适合场景 退出终端是否稳定 是否支持开机自启 是否方便管理
& 临时后台任务 不稳定 不支持 一般
nohup + & 长时间脚本 较稳定 不支持 一般
tmux/screen 交互式会话 稳定 不支持 适合调试
systemd 正式服务 稳定 支持 很方便

选择建议:

text 复制代码
临时跑一下:&
退出终端继续跑:nohup
需要交互会话:tmux/screen
正式服务部署:systemd

12. 常见问题

12.1 nohup 启动后马上退出

先看日志:

bash 复制代码
cat app.log
cat nohup.out

常见原因:

  • 工作目录不对;
  • 配置文件路径错误;
  • 端口被占用;
  • 环境变量缺失;
  • 程序启动时报错。

12.2 systemd 手动运行正常,服务运行失败

常见原因是 systemd 环境变量较少,不会自动加载用户的 .bashrc

解决思路:

  • 使用绝对路径;
  • 配置 WorkingDirectory
  • 配置 Environment
  • 指定正确 User
  • journalctl -u 服务名 看日志。

示例:

ini 复制代码
Environment=JAVA_HOME=/usr/lib/jvm/java-17
Environment=PATH=/usr/local/bin:/usr/bin:/bin

13. 小结

Linux 后台任务可以这样记:

text 复制代码
&:放到当前 shell 后台
jobs:看当前 shell 的任务
fg/bg:前后台切换
nohup:退出终端继续运行
systemd:正式服务管理

常用命令:

bash 复制代码
command &
jobs
fg %1
bg %1
nohup command > app.log 2>&1 &
systemctl status myapp
journalctl -u myapp -f

如果只是临时执行脚本,用 nohup 就够。

如果是线上服务,建议写成 systemd 服务。

相关推荐
用户23678298016811 小时前
Linux scp 命令详解:安全文件传输的底层原理与实战技巧
linux
Harm灬小海11 小时前
【云计算学习之路】企业常用服务搭建:MySQL 8.0
linux·运维·学习·mysql·云计算
杨云龙UP11 小时前
Oracle Flashback Query 实战练习:误更新、误删除数据如何快速找回?
linux·运维·数据库·sql·oracle·flashback
skyutuzz11 小时前
容器tini
linux·笔记
Nick.Q11 小时前
Ubuntu 24.04 从零跑通 OpenTitan:IC 验证工程师实录(Verilator + VCS + Verdi)
linux·ubuntu·systemverilog
dadaobusi11 小时前
现代服务器是否还有pcie io访问的设备?
linux
刘某的Cloud11 小时前
ceph-s & ceph_osd_tree_ceph缩容恢复_集群状态.md
linux·运维·服务器·ceph
say_fall11 小时前
操作系统与进程核心全解:从冯诺依曼到fork系统调用
android·linux·运维·服务器·学习·ubuntu
Bert.Cai11 小时前
Linux test命令详解
linux·运维·服务器