Linux 前后台任务切换与查看
前言
通过 SSH 连上 Linux 服务器后,我们常在当前终端里跑编译、备份或日志 tail 等耗时命令。
若任务占着前台,同一窗口就没法继续敲别的命令;若直接关终端,未妥善处理的进程还可能被一起杀掉。
本文只讲当前 Shell 会话内的前后台切换与查看,不涉及 systemd 服务或容器编排。
下文命令在常见 Bash 环境下均可使用,其他 Shell 行为可能略有差异。
实现
基本概念
Shell 把正在占用终端输入输出的命令叫前台任务,不占用终端、在后台继续跑的叫后台任务。
同一终端里,前台通常同时只能有一个任务在跑;被挂起或转入后台的任务会挂在当前 Shell 的作业表里,用 jobs 查看。
作业号是 Shell 给任务编的号(如 [1]),PID 是系统进程号;fg、bg 用的是作业号,查系统进程用 ps 等。
挂起当前任务
前台任务运行中,按 Ctrl+Z 会向进程发送 SIGTSTP,任务暂停并回到 Shell 提示符。
下面用 sleep 模拟一个长时间任务,挂起后再查看作业表。
1 | sleep 300 |
-l 会同时显示 PID,便于和 ps 对照。
转入后台
挂起后的任务用 bg 恢复运行,但不再占用前台。
若已知作业号,可写 bg %1;只有一个挂起任务时,直接 bg 即可。
1 | bg |
也可以启动时就放后台:在命令末尾加 &。
1 | tail -f /var/log/syslog & |
带 & 启动的任务会立刻进入后台,输出仍可能混进当前终端;需要完全静默时见下文 nohup 与重定向。
恢复前台
要把后台或挂起中的任务调回前台,用 fg。
同样可用作业号,例如 %1 表示 1 号作业;fg 不带参数时,默认取「当前作业」(通常是最新一个)。
1 | fg %1 |
任务回到前台后,终端再次被它占用,直到结束、挂起或你开新窗口操作别的会话。
查看任务
jobs 只看当前 Shell 会话里的作业,换了一个 SSH 窗口或新开终端是看不到的。
1 | jobs |
-l 列出 PID;-p 只打印 PID,方便脚本里批量处理。
要看整机上某用户或某命令的进程,用 ps 或 top。
1 | ps -u "$USER" -o pid,stat,cmd |
STAT 里 T 常表示被挂起(stopped),R 为运行,S 为可中断睡眠。
新会话查找
新开一个 SSH 窗口后,jobs、fg、bg 都无效,因为作业表只属于原来那个 Shell。
后台任务若仍在运行,在系统里已是普通进程,只能按 PID 或命令名去查、去管。
先在原窗口用 jobs -l 记下 PID,再到新窗口核对是否还在。
1 | # 原窗口 |
新窗口里按 PID 或关键字查找同一进程。
1 | ps -p 12345 -o pid,stat,cmd |
确认后可用 kill 结束;不能在新窗口写 fg %1 或 kill %1,%1 只认当前 Shell 的作业号。
1 | kill 12345 |
若原 SSH 已断开且当时没用 nohup、disown 或 tmux,后台任务可能已被 SIGHUP 终止,新会话里自然查不到。
需要「换窗口还能接回来」,应在一开始就 detached 跑(见下节),或直接用 tmux。
脱离终端
SSH 断开时,Shell 往往会给其下的作业发 SIGHUP,未脱离的任务可能被终止。
临时跑长任务时,可用 nohup 忽略挂断信号,并把输出写到文件。
1 | nohup ./long-task.sh > task.log 2>&1 & |
disown -h 让已在后台的作业不再受当前 Shell 的 SIGHUP 影响;-h 表示标记为「忽略挂断」,进程仍在,只是从作业表里「脱钩」。
更稳妥的生产做法仍是 systemd;需要交互式长跑、多窗口看日志时,见下文 多窗口协作。
扩展
结束任务
前台任务用 Ctrl+C 发 SIGINT 结束。
已知 PID 时可用 kill;挂起中的作业也可 kill %1 按作业号结束。
1 | kill %1 |
-9 为强制杀死,正常应先试不带信号的 kill 或 kill -15。
多窗口协作
jobs/fg/bg 只能管当前 Shell;SSH 一断,普通后台任务还可能被 SIGHUP 杀掉。
tmux 与 screen 在服务器上跑一个「终端 multiplexer」:任务跑在 tmux/screen 会话里,SSH 断开或换窗口后,进程照常运行,随时 attach 回来继续看输出、敲命令。
选型
| 工具 | 特点 |
|---|---|
| tmux | 分屏、配置灵活,近年更常用 |
| screen | 更老、很多老机器自带,语法略不同 |
下文以 tmux 为主;会 screen 的同学,把 detach/attach 换成 Ctrl+A D / screen -r 即可。
安装
多数发行版仓库里都有,按需安装(包名以系统为准)。
1 | # Debian / Ubuntu |
创建与脱离
给会话起个名字,方便日后找回;在 tmux 里启动的任务与普通 Shell 一样,可前台跑、也可 Ctrl+Z + bg。
1 | tmux new -s build |
脱离(detach):任务继续跑,SSH 可以关。
默认前缀键是 Ctrl+B,松开后按 D(大写 d 或小写 d 均可,习惯写 D)。
1 | # 等价命令(在 tmux 外也可执行,需知道会话名) |
脱离后,编译、部署等输出仍写入该 tmux 会话,不会因关笔记本而中断。
重新接入
新开 SSH 后,先列出仍在跑的 tmux 会话,再 attach 到目标会话。
1 | tmux ls |
接入后界面与离开前一致,滚动可看到历史输出(tmux 有回滚缓冲)。
若提示 no sessions,说明会话已被关掉或服务器重启后未恢复。
会话管理
1 | # 列出会话 |
一个 SSH 连接里可以 attach 多个 tmux 会话,但同一时刻只能 attach 进一个;换会话先 detach 或开新 SSH。
窗口与分屏
一个 tmux 会话里可有多个窗口(类似浏览器标签);窗口里还可分 pane 并排看日志与 shell。
在 tmux 内常用快捷键(先按 Ctrl+B 松开,再按后面键):
| 按键 | 作用 |
|---|---|
C |
新建窗口 |
N / P |
下一 / 上一窗口 |
" |
上下分屏 |
% |
左右分屏 |
| 方向键 | 在 pane 间切换 |
X |
关闭当前 pane |
[ |
进入复制/滚动模式,方向键或 PageUp 翻历史,按 q 退出 |
例如部署时一 pane 跑 ./deploy.sh,另一 pane tail -f deploy.log,断线重连后布局仍在。
screen 简要用法
未装 tmux、只有 screen 时,流程类似。
1 | screen -S build |
结束 screen 会话:在会话内输入 exit,或 screen -X -S build quit。
和 jobs 的区别
| 方式 | 作用范围 | SSH 断开后 | 新窗口「接回」 |
|---|---|---|---|
bg / jobs |
当前 Shell 作业表 | 易被杀(除非 nohup/disown) | 不能 fg,只能 ps + kill |
| tmux / screen | 独立终端会话 | 进程通常继续 | tmux attach / screen -r |
建议:临时短命令用 & + jobs 即可;编译、训练、长时间 tail 等,优先 tmux new -s 名字 再跑任务。
生产环境长期服务仍应用 systemd,tmux 适合人工盯过的交互式长任务。
总结
Ctrl+Z挂起前台任务,bg转后台继续跑,fg拉回前台。- 命令末尾加
&可启动时即后台;jobs -l查看本 Shell 作业与 PID。 - 查系统级进程用
ps、top,不要和jobs混为一谈。 - 新 SSH 窗口看不到原 Shell 的
jobs;用ps/pgrep按 PID 管理,不能用fg %1。 - SSH 长跑任务用
nohup与disown,或改用 tmux(new→ 跑任务 →Ctrl+B D脱离 → 新窗口attach),避免断线误杀。