当前位置:首页>Linux>Linux 从0到1 : 09 · 进程与作业管理

Linux 从0到1 : 09 · 进程与作业管理

  • 2026-10-11 07:02:29
Linux 从0到1 : 09 · 进程与作业管理
     欢迎来到罐子的实验室
    今天来学习进程与作业管理

    本次目标

    理解「进程」是什么,学会查看、终止、挂起、前后台切换正在运行的程序,读懂退出码。

学完你能做什么:

  • 用 ps 查看系统里跑着哪些进程
  • 用 kill 终止卡死的程序
  • 用 Ctrl-C / Ctrl-Z / fg / bg 控制前台后台
  • 看懂 $? 退出码
  • 区分「挂起」「后台运行」「终止」

1. 进程是什么

每当你运行一个命令,Linux 内核就给它分配一个进程(process)——一个正在运行的程序实例,带一个唯一的编号 PID(进程 ID)。

你的 Shell 是个进程,你跑的 ls、vim、浏览器都是进程。开机时 Linux 启动第一个进程(PID 1),它再启动一堆别的进程,层层派生。

管理这些进程——看它们、停它们、让它们后台跑——就是本模块的内容。


2. ps:列出进程

ps(process status)列出进程。最常用的两种写法:

user@host:~$ ps -ef# 标准语法,-e 全部,-f 完整格式UID PID PPID C STIME TTY TIME CMDroot 1 0 0 09:00 ? 00:00:02 /sbin/inituser 500 1 0 09:01 ? 00:00:00 /usr/lib/code-serveruser 800 500 0 09:02 pts/0 00:00:00 bashuser 900 800 0 09:03 pts/0 00:00:00 ps -ef

或:

user@host:~$ ps aux# BSD 语法,a 所有用户,u 详细,x 无终端的也显示USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND...

两种都行,记一种就够。关键列:

列
含义
PID
进程 ID(最重要,kill 要用)
PPID
父进程 ID(谁启动了它)
USER
启动它的用户
%CPU
/%MEM
占用的 CPU/内存百分比
STAT
进程状态(见第 7 节)
COMMAND
完整命令行

💡 输出可能被终端宽度截断,看不全命令。用 ps -efww 或 ps auxww(两个 w)禁用截断。

动手练习 1:找到自己的进程

任务:列出所有你启动的进程。

思路引导:ps -u $USER 或 ps -ef | grep $USER。

参考答案:

user@host:~$ ps -u $USER PID TTY TIME CMD 800 pts/0 00:00:00 bash 900 pts/0 00:00:00 ps

常见错误:ps 不带任何参数只列当前终端的进程,看不到系统全局的——要 -e 或 aux。


3. kill:终止进程

kill 给进程发信号,默认发的是 TERM(终止),让进程「体面地」结束:

user@host:~$ sleep 1000 &# 启动个后台 sleep[1] 12345# 它的 PID 是 12345user@host:~$ kill 12345# 用 PID 杀它user@host:~$

kill 的参数是 PID,不是进程名。先 ps 找到 PID,再 kill。

信号类型

信号
编号
含义
TERM
15
请求终止(默认,进程可清理后退出)
KILL
9
强制
杀死(不可阻挡,进程没机会清理)
INT
2
中断(相当于 Ctrl-C)
STOP
19
暂停(不可阻挡)
CONT
18
继续

kill -9 PID 是「核选项」——进程卡死、不理 TERM 时才用。kill -9 会让程序来不及保存数据就死。

user@host:~$ kill 12345# 先礼后兵:发 TERMuser@host:~$ kill -9 12345# 还不死?发 KILL

💡 按 PID 杀要先用 ps 查;pkill 名字 和 killall 名字 可以按名字杀,但要小心匹配范围。

动手练习 2:杀掉一个 sleep

任务:

  1. 启动 sleep 300 &(后台运行 5 分钟)。
  2. 用 ps 找到它的 PID。
  3. kill
     它,再用 ps 确认它没了。

参考答案:

user@host:~$ sleep 300 &[1] 12345user@host:~$ ps | grep sleep12345 pts/0 00:00:00 sleepuser@host:~$ kill 12345user@host:~$ ps | grep sleep# 没输出,说明已终止

常见错误:

  • ❌ kill sleep(传了名字)→ kill: kill sleep: no such process,kill 要 PID。
  • ⚠️ 杀了别人的进程会 Operation not permitted——你只能杀自己的(root 除外,→ 详见《模块 10》)。

4. Ctrl-C:中断前台进程

如果一个程序占着你的终端(前台运行),按 Ctrl-C 给它发中断信号,通常能让它退出:

user@host:~$ sleep 1000^C# 按 Ctrl-Cuser@host:~$

Ctrl-C 是「我想停掉这个」最常用的快捷键。

动手练习 3:中断一个长任务

任务:运行 sleep 1000(前台),然后用 Ctrl-C 中断它,确认回到提示符。

参考答案:

user@host:~$ sleep 1000^Cuser@host:~$

常见错误:Ctrl-C 只能中断前台进程,后台进程要用 kill。


5. Ctrl-Z:挂起(不终止)

Ctrl-Z 把前台进程挂起(suspend,暂停)并放回后台,不终止它——你可以稍后恢复:

user@host:~$ sleep 1000^Z[1]+ Stopped sleep 1000user@host:~$

[1] 是作业号(job 1),Stopped 表示它被暂停了。现在你能继续在终端敲别的命令,那个 sleep 还「活着」但不动。

动手练习 4:挂起一个任务

任务:运行 sleep 1000,挂起它,然后 ps 看它还在不在(只是 Stopped 状态)。

参考答案:

user@host:~$ sleep 1000^Z[1]+ Stopped sleep 1000user@host:~$ ps PID ... STAT CMD 12345 ... T sleep 1000# STAT 是 T,表示 stopped

💡 STAT 列含义见第 7 节,T = stopped。


6. fg / bg / &:前后台切换

挂起之后怎么办?

  • fg
    (foreground)把挂起的进程恢复到前台继续运行。
  • bg
     把挂起的进程放到后台继续运行(但它不再占终端)。
  • 命令 &
     直接让命令在后台启动。
user@host:~$ sleep 1000^Z[1]+ Stopped sleep 1000user@host:~$ bg# 放后台继续跑[1]+ sleep 1000 &user@host:~$ fg# 又拉回前台sleep 1000^C# 不想要了,Ctrl-C 终止user@host:~$

直接后台启动:

user@host:~$ sleep 1000 &[1] 12345user@host:~$# 立刻回到提示符,sleep 在后台跑

有多个后台作业时用作业号指定:fg %1、bg %2。jobs 命令列出当前所有作业。

动手练习 5:前后台切换

任务:

  1. 后台启动 sleep 1000 &。
  2. 用 fg 拉回前台。
  3. Ctrl-Z
     挂起,再用 bg 放回后台。
  4. jobs
     看状态。

参考答案:

user@host:~$ sleep 1000 &[1] 12345user@host:~$ fgsleep 1000^Z[1]+ Stopped sleep 1000user@host:~$ bg[1]+ sleep 1000 &user@host:~$ jobs[1]+ Running sleep 1000 &

常见错误:fg / bg 不带参数只对最近一个作业操作,多个作业会混淆——养成用 %N 指定的习惯。


7. STAT 列:看进程状态

ps 的 STAT 列用字母表示进程当前状态:

字母
含义
R
running / runnable(运行中或等待 CPU)
S
interruptible sleep(可中断睡眠,大多数进程常态)
D
uninterruptible sleep(深度睡眠,通常在等 IO)
T
stopped(被 Ctrl-Z 或信号暂停)
Z
zombie(僵尸进程,已死但父进程没回收)

附加符号:

符号
含义
+
在前台
<
高优先级
s
会话首领
l
多线程

例:

  • Ss
     —— 睡眠的会话首领(典型如 bash)
  • R+
     —— 前台正在运行(典型如你刚敲的 ps)
  • T
     —— 被挂起

动手练习 6:解读状态

任务:挂起一个 sleep,用 ps -o pid,stat,cmd 看它的 STAT。

参考答案:

user@host:~$ sleep 1000^Z[1]+ Stopped sleep 1000user@host:~$ ps -o pid,stat,cmd PID STAT CMD 800 Ss bash 12345 T sleep 1000 ← T 表示 stopped 12346 R+ ps -o pid,stat,cmd ← R+ 表示前台运行

8. 退出码 $?

每个命令结束都返回一个退出码(exit code):0 表示成功,非 0 表示失败(具体数字代表不同错误)。

用 $? 读取上一条命令的退出码(→ 变量详见《模块 08》):

user@host:~$ ls /etc > /dev/nulluser@host:~$ echo $?0# 成功user@host:~$ ls /不存在ls: cannot access '/不存在': No such file or directoryuser@host:~$ echo $?2# 失败,码 2

退出码是命令间协作的基础——&&、||、if 都靠它判断(→ 详见《模块 11》)。

动手练习 7:判断成功

任务:写一条命令——「如果 /etc/passwd 存在就打印 OK」。用 test -f /etc/passwd && echo OK。

参考答案:

user@host:~$ test -f /etc/passwd && echo OKOKuser@host:~$ test -f /nope && echo OK# 不打印,因为 test 失败

(test -f 文件 在文件存在时返回 0。)


9. 实战场景:排查卡死的进程

真实工作中常遇到:某个程序卡死、占 CPU 100%、或者端口被占用。排查套路:

  1. ps aux | grep 程序名
     找到它的 PID 和状态。
  2. 看 %CPU/%MEM 是否异常高。
  3. kill PID
     试温和终止;不行就 kill -9 PID。
  4. 端口占用用 ss -tlnp | grep 端口号(需要 root 看进程名)。

动手练习 8:模拟排查

任务:

  1. 后台启动 sleep 999 &。
  2. ps aux | grep sleep
     找到它。
  3. kill
     掉它。

参考答案:

user@host:~$ sleep 999 &[1] 12345user@host:~$ ps aux | grep '[s]leep'# [s]leep 技巧避免 grep 匹配到自己user 12345 ... sleep 999user@host:~$ kill 12345

💡 ps aux | grep sleep 会把 grep sleep 自己也列出来(因为它含 sleep 字样)。写 grep '[s]leep' 是个老技巧:正则 [s]leep 匹配 sleep,但不匹配字面的 [s]leep,于是排除了 grep 自己。


本模块速查表

命令 / 操作
作用
ps -ef
 / ps aux
列出所有进程
ps -u $USER
列出自己的进程
kill PID
终止进程(发 TERM)
kill -9 PID
强制杀死
Ctrl-C
中断前台进程
Ctrl-Z
挂起前台进程
fg
 / bg
把挂起进程拉到前/后台
命令 &
后台启动
jobs
列出当前作业
$?
上条命令退出码

STAT 字母速记

R=运行 S=睡眠 D=深度睡眠 T=暂停 Z=僵尸+=前台 s=会话首领 l=多线程

kill 信号

TERM(15)=请求终止(默认)KILL(9)=强制杀死(核选项)INT(2)=中断(同 Ctrl-C)

下一步

你启动的进程都以「你自己」的身份运行。但 Linux 是多用户系统——谁能做什么,由用户和权限决定。这是 Linux 安全的地基。

最新文章

随机文章