Linux 前后台任务切换与查看

前言

通过 SSH 连上 Linux 服务器后,我们常在当前终端里跑编译、备份或日志 tail 等耗时命令。
若任务占着前台,同一窗口就没法继续敲别的命令;若直接关终端,未妥善处理的进程还可能被一起杀掉。
本文只讲当前 Shell 会话内的前后台切换与查看,不涉及 systemd 服务或容器编排。
下文命令在常见 Bash 环境下均可使用,其他 Shell 行为可能略有差异。

实现

基本概念

Shell 把正在占用终端输入输出的命令叫前台任务,不占用终端、在后台继续跑的叫后台任务
同一终端里,前台通常同时只能有一个任务在跑;被挂起或转入后台的任务会挂在当前 Shell 的作业表里,用 jobs 查看。
作业号是 Shell 给任务编的号(如 [1]),PID 是系统进程号;fgbg 用的是作业号,查系统进程用 ps 等。

挂起当前任务

前台任务运行中,按 Ctrl+Z 会向进程发送 SIGTSTP,任务暂停并回到 Shell 提示符。
下面用 sleep 模拟一个长时间任务,挂起后再查看作业表。

1
2
3
sleep 300
# 按 Ctrl+Z
jobs -l

-l 会同时显示 PID,便于和 ps 对照。

转入后台

挂起后的任务用 bg 恢复运行,但不再占用前台。
若已知作业号,可写 bg %1;只有一个挂起任务时,直接 bg 即可。

1
2
bg
jobs -l

也可以启动时就放后台:在命令末尾加 &

1
2
tail -f /var/log/syslog &
jobs -l

& 启动的任务会立刻进入后台,输出仍可能混进当前终端;需要完全静默时见下文 nohup 与重定向。

恢复前台

要把后台或挂起中的任务调回前台,用 fg
同样可用作业号,例如 %1 表示 1 号作业;fg 不带参数时,默认取「当前作业」(通常是最新一个)。

1
fg %1

任务回到前台后,终端再次被它占用,直到结束、挂起或你开新窗口操作别的会话。

查看任务

jobs 只看当前 Shell 会话里的作业,换了一个 SSH 窗口或新开终端是看不到的。

1
2
3
jobs
jobs -l
jobs -p

-l 列出 PID;-p 只打印 PID,方便脚本里批量处理。
要看整机上某用户或某命令的进程,用 pstop

1
2
3
ps -u "$USER" -o pid,stat,cmd
ps aux | grep tail
top -u "$USER"

STATT 常表示被挂起(stopped),R 为运行,S 为可中断睡眠。

新会话查找

新开一个 SSH 窗口后,jobsfgbg无效,因为作业表只属于原来那个 Shell。
后台任务若仍在运行,在系统里已是普通进程,只能按 PID 或命令名去查、去管。

先在原窗口jobs -l 记下 PID,再到新窗口核对是否还在。

1
2
3
# 原窗口
jobs -l
# [1]+ 12345 Running tail -f /var/log/syslog &

新窗口里按 PID 或关键字查找同一进程。

1
2
3
ps -p 12345 -o pid,stat,cmd
pgrep -af tail
ps -u "$USER" -o pid,stat,cmd | grep tail

确认后可用 kill 结束;不能在新窗口写 fg %1kill %1%1 只认当前 Shell 的作业号。

1
2
kill 12345
kill -15 12345

若原 SSH 已断开且当时没用 nohupdisown 或 tmux,后台任务可能已被 SIGHUP 终止,新会话里自然查不到。
需要「换窗口还能接回来」,应在一开始就 detached 跑(见下节),或直接用 tmux。

脱离终端

SSH 断开时,Shell 往往会给其下的作业发 SIGHUP,未脱离的任务可能被终止。
临时跑长任务时,可用 nohup 忽略挂断信号,并把输出写到文件。

1
2
3
nohup ./long-task.sh > task.log 2>&1 &
disown -h %1
jobs -l

disown -h 让已在后台的作业不再受当前 Shell 的 SIGHUP 影响;-h 表示标记为「忽略挂断」,进程仍在,只是从作业表里「脱钩」。
更稳妥的生产做法仍是 systemd;需要交互式长跑、多窗口看日志时,见下文 多窗口协作

扩展

结束任务

前台任务用 Ctrl+CSIGINT 结束。
已知 PID 时可用 kill;挂起中的作业也可 kill %1 按作业号结束。

1
2
3
kill %1
kill 12345
kill -9 12345

-9 为强制杀死,正常应先试不带信号的 killkill -15

多窗口协作

jobs/fg/bg 只能管当前 Shell;SSH 一断,普通后台任务还可能被 SIGHUP 杀掉。
tmuxscreen 在服务器上跑一个「终端 multiplexer」:任务跑在 tmux/screen 会话里,SSH 断开或换窗口后,进程照常运行,随时 attach 回来继续看输出、敲命令。

选型

工具 特点
tmux 分屏、配置灵活,近年更常用
screen 更老、很多老机器自带,语法略不同

下文以 tmux 为主;会 screen 的同学,把 detach/attach 换成 Ctrl+A D / screen -r 即可。

安装

多数发行版仓库里都有,按需安装(包名以系统为准)。

1
2
3
4
5
6
7
8
# Debian / Ubuntu
sudo apt install tmux

# CentOS / RHEL
sudo yum install tmux

# 查看是否已安装
tmux -V

创建与脱离

给会话起个名字,方便日后找回;在 tmux 里启动的任务与普通 Shell 一样,可前台跑、也可 Ctrl+Z + bg

1
2
3
tmux new -s build
# 在 tmux 内执行长任务,例如:
./deploy.sh

脱离(detach):任务继续跑,SSH 可以关。
默认前缀键是 Ctrl+B,松开后按 D(大写 d 或小写 d 均可,习惯写 D)。

1
2
# 等价命令(在 tmux 外也可执行,需知道会话名)
tmux detach -s build

脱离后,编译、部署等输出仍写入该 tmux 会话,不会因关笔记本而中断。

重新接入

新开 SSH 后,先列出仍在跑的 tmux 会话,再 attach 到目标会话。

1
2
3
4
5
6
tmux ls
# build: 1 windows (created Thu Jul 23 18:00:00 2026)

tmux attach -t build
# 简写
tmux a -t build

接入后界面与离开前一致,滚动可看到历史输出(tmux 有回滚缓冲)。
若提示 no sessions,说明会话已被关掉或服务器重启后未恢复。

会话管理

1
2
3
4
5
6
7
8
9
10
# 列出会话
tmux ls

# 新建(已有 tmux 时开第二个会话)
tmux new -s logs

# 结束整个会话(会话内所有窗口一起退出)
tmux kill-session -t build

# 重命名当前会话(在 tmux 内:Ctrl+B 再按 $)

一个 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
2
3
4
5
6
screen -S build
./long-task.sh
# 脱离:Ctrl+A 然后按 D

screen -ls
screen -r 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 适合人工盯过的交互式长任务

总结

  1. Ctrl+Z 挂起前台任务,bg 转后台继续跑,fg 拉回前台。
  2. 命令末尾加 & 可启动时即后台;jobs -l 查看本 Shell 作业与 PID。
  3. 查系统级进程用 pstop,不要和 jobs 混为一谈。
  4. 新 SSH 窗口看不到原 Shell 的 jobs;用 ps/pgrep 按 PID 管理,不能用 fg %1
  5. SSH 长跑任务用 nohupdisown,或改用 tmuxnew → 跑任务 → Ctrl+B D 脱离 → 新窗口 attach),避免断线误杀。