jobs 是 shell 的后台作业仪表盘,只显示当前会话中由用户启动且未被清理的作业,含 running、stopped 和刚退出的残留项,不显示其他终端或 nohup 启动的任务。

怎么一眼看出哪个任务在前台、哪个卡住了
终端里跑着几个命令,一时间分不清谁在干活、谁被按了暂停键——jobs 就是你的“后台仪表盘”。它不查进程树,只列当前 shell 会话里你亲手启的作业(job),包括还在跑的、被 Ctrl+Z 挂起的、甚至刚退出但还没被 shell 清掉的残留项。
-
jobs默认只显示状态为Running或Stopped的活跃作业,带[1]+这种编号,+表示最近一个被挂起/后台化的任务,-是倒数第二个 - 加
-l参数(即jobs -l)能同时看到 PID,方便后续用kill精准处理,比如发现[2]- Stopped vim notes.txt,PID 是 5821,那kill 5821比kill %2更稳妥(尤其在子 shell 中) - 注意:
jobs不显示其他终端或 nohup 启动的任务,也看不到已Terminated且 shell 已清理掉的作业——它只管“自己生的、还没断奶的”
fg %1 和直接敲 fg,到底恢复哪个任务
很多人试过 fg 没反应,或者恢复了错的任务——问题不在命令写错,而在没理解“作业标记”的优先级规则。
- 不带参数的
fg永远恢复标有+的那个作业,也就是你最近一次Ctrl+Z或bg操作的对象 -
fg %1明确指定编号 1 的作业;fg %-恢复标有-的那个(即次新任务);fg %?(问号需替换为部分命令名,如%py)可模糊匹配含 “py” 的作业,适合记不清编号时快速定位 - 坑点:如果某任务已退出(比如脚本自然结束),
jobs可能还短暂显示[1] Done sleep 10,此时fg %1会报错bash: fg: %1: no such job——不是命令失效,是作业生命周期结束了
bg %1 后任务“消失”了?输出去哪了
bg 不是魔法,它只是把挂起的进程从“暂停态”切到“后台运行态”,但不会接管它的输入输出流。所以你常会发现:任务明明在跑,终端却没动静,日志也不见了。
- 默认情况下,后台任务的标准输出(stdout)和标准错误(stderr)仍连在当前终端,只是不再自动刷屏——如果程序持续打印,内容其实还在,只是被前台命令的输出盖过去了;一旦前台命令退出,那些积压的日志可能突然涌出
- 真正“静默”运行要靠重定向:
bg %1 > out.log 2>&1可以补救,但更推荐启动时就写好,比如python train.py > log.txt 2>&1 & - 关键限制:后台任务无法读取键盘输入(
stdin被关闭),所以交互式程序(如vim、top)用bg强行扔后台会卡死或报错Input/output error
关掉终端后任务还在吗?什么情况下会丢进程
答案很干脆:普通 & 或 bg 启动的任务,**关终端就死**。这不是 bug,是 Linux 会话机制的设计使然。
- 终端关闭 → shell 收到
SIGHUP→ 默认向所有子作业发送SIGHUP→ 大多数进程收到就退出 - 想“真后台”,必须绕过这个信号:
nohup command &是最简解法,它让进程忽略SIGHUP并自动把输出追加到nohup.out;更彻底的做法是setsid command &,让它脱离当前会话,成为独立会话组长 - 容易忽略的一点:即使用了
nohup,如果你是通过 SSH 登录,而 SSH 客户端异常断开(比如网络闪断),某些老版本 OpenSSH 仍可能触发SIGHUP——这时得配合tmux或screen才算保险
作业管理不是功能堆砌,而是对“谁在控制终端、谁该响应信号、谁该继承 I/O”的持续确认。哪怕只是多敲一次 jobs -l,也比凭记忆猜 %3 是不是那个正在下载大模型的 Python 进程来得实在。










