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 服务。

相关推荐
A_humble_scholar4 小时前
Linux(九) 进程管理完全指南:从入门到实战
linux·运维·chrome
江华森5 小时前
Linux 操作命令完全指南
linux·运维
rjszcb5 小时前
Linux,sensor调试笔记1,修改帧率,以及曝光上不去问题
linux
C++ 老炮儿的技术栈5 小时前
Ubuntu root账号自动登陆
linux·运维·服务器·c语言·c++·ubuntu·visual studio
2301_780789665 小时前
零信任架构中,身份感知防火墙(IAFW)的部署要点与最佳实践
linux·运维·服务器·人工智能·tcp/ip·架构
小狮子&6 小时前
ubuntu2604无法共享文件夹问题解决
linux·运维·服务器
biter down6 小时前
3:VMware Workstation 安装 Ubuntu 22.04 超详细教程
linux·运维·ubuntu
曾阿伦6 小时前
netcat / ncat / socat 用法详解与示例
linux·http·信息与通信
Benszen6 小时前
Secret详解
linux·运维·服务器
Dlrb12117 小时前
Linux网络编程-网络基础概念(IP, UDP协议)
linux·服务器·网络·网络基础·端口号·ip协议·udp协议