type: learning-note
title: Linux:systemctl 操作与起不来初探
date: 2026-10-14
description: 自己写 unit 文件并让它跑起来;daemon-reload 的两种情形(只改描述 vs 改启动命令);start/stop/restart 与 is-active;status 一屏怎么读(三个符号、Loaded 与 Active 两个轴、TriggeredBy、Duration);enable/disable 建删软链;Type=simple 导致的"start 不报错但服务 failed";从 failed 往下第一跳(status 底部日志 / journalctl -u);退出码表(LSB 那套、0/3/4 的分工);收拾现场三层清理
2026-10-14 学习笔记
笔记区
核心观点
**一、最小 unit 文件与它放哪**
- 一个能跑起来的服务,文件里最少三行(每段一行):
```ini
Unit
Description=Hello Test Service
Service
ExecStart=/bin/sleep infinity
Install
WantedBy=multi-user.target
```
| 行 | 写在哪段 | 管什么 |
| -------------- | ----------- | ------------------------------------------------------------------------------------------- |
| `Description=` | `Unit` | 给**人**看的名字(`systemctl status` 第一行显示它)。**随便填** |
| `ExecStart=` | `Service` | 启动时**跑哪个程序**(**绝对路径** + 参数)。`/bin/sleep infinity` = 永远睡,进程不会自己退 |
| `WantedBy=` | `Install` | `enable` 时**挂到哪个 target 下面**。**必须填系统里真有的 target 名**(带 `.target`) |
-
**放哪**:`/etc/systemd/system/` ------ 回扣 10-13 讲的三层目录,这层是**管理员**放的,优先级最高。
-
**`WantedBy=` 填错会怎样**(实测两种):
-
填 `World`(**不带后缀**)→ `enable` 直接报 **`Failed to enable unit: Invalid unit name World`**,退出码 1
-
填 `World.service`(**带后缀但系统里没这个 unit**)→ `enable` **不报错**、照样建 `World.service.wants/` 目录,**但多一句警告** `is added as a dependency to a non-existent unit` ------ **开机根本没人读那个目录,等于白干**
-
填 `multi-user.target`(真实存在)→ 正常
-
**`multi-user.target` 是哪来的**:**系统自带的**,不是谁写的。
-
`systemctl list-unit-files multi-user.target` → 状态是 `static`
-
`systemctl show multi-user.target -p FragmentPath` → `/usr/lib/systemd/system/multi-user.target`(**发行版装包时装的**那层)
-
**能填哪些 target** → `systemctl list-units --type=target`(本机 23 个)。服务器上的常驻服务基本都挂 `multi-user.target`。
**二、怎么验证自己写的东西(两件工具)**
| 要验什么 | 用什么 | 怎么判 |
| -------------------------- | ---------------------------------------------------------- | ---------------------------------------------------- |
| **文件写得对不对**(语法) | `systemd-analyze verify /etc/systemd/system/hello.service` | **没输出 = 合法**;有输出它会带**文件名:行号**指出来 |
| **服务真不真跑得起来** | 先 `start`,再 `is-active` / `status` | 见下面点三、点四 |
-
**硬判据是退出码**:`echo $?` ------ **0 = 成功,非 0 = 失败**。
-
实测对照:把 `ExecStart=` 写成小写 `Execstart=`(错误拼法),`verify` 直接报
```
/tmp/bad.service:5: Unknown key 'Execstart' in section Service, ignoring.
bad.service: Service has no ExecStart=, ExecStop=, or SuccessAction=. Refusing.
Unit bad.service has a bad unit file setting.
退出码 = 1
```
**三、`daemon-reload` ------ 两种情形不一样(实测分出)**
-
**它干什么**(`man 1 systemctl` 原文):`Reload the systemd manager configuration. This will rerun all generators, reload all unit files, and recreate the entire dependency tree.` ------ 让 systemd 把磁盘上的单元文件**整个重读一遍**、依赖树重搭。
-
**它为什么存在**:systemd 把配置**加载进内存**跑;磁盘上改了,内存里那份就过时了。
-
⭐ **实测分两种情形**(差别在"改动影响不影响行为"):
| 改了什么 | 不跑 `daemon-reload` 会怎样 |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `Description=`(**只影响显示**) | `systemctl show -p Description` **直接看到新值** |
| **`ExecStart=`(影响"怎么跑")** | ⚠️ systemd **警告** `Run 'systemctl daemon-reload' to reload units.`;而且 **`restart` 之后跑的还是旧程序** |
-
**另一个实测**(服务**没在跑**时改 `ExecStart=`,不 reload 直接起):**跑的是新值**。
-
**所以准确说法**:`daemon-reload` 是把**内存里那份**换成磁盘上最新的;**当 systemd 要用"内存那份"时**(服务已在跑),不 reload 就用旧的。手册也承认它不是唯一入口 ------ `man 5 systemd.unit:372`:`Use systemctl daemon-reload or an equivalent command to reload unit configuration while the unit is already ...`(**或一条等价的命令**)。
**四、`start` / `stop` / `restart` + 一个问句**
| 命令 | 干什么 | 要 `sudo` 吗 |
| ---------------------------- | ---------------------------- | ------------ |
| `systemctl start <服务>` | **现在开始跑** | 要 |
| `systemctl stop <服务>` | **现在停下** | 要 |
| `systemctl restart <服务>` | **停再起**(= stop + start) | 要 |
| `systemctl is-active <服务>` | **问一句:现在在不在跑** | 不要 |
-
前三条**改系统状态**(所以 `sudo`);`is-active` 只是问。
-
**`restart` 和 `start` 的差别**:服务**已经在跑**时,`start` 什么都不做、`restart` 才"先停再起";服务**已经停了**时,两条**效果一样**。
-
实测:`start` / `stop` / `restart` **成功时都没有输出**,退出码都是 0。
**五、读懂 `systemctl status` 那一屏**
-
**它和 `show` 的分工**(`man 1 systemctl`):`This function is intended to generate human-readable output. If you are looking for computer-parsable output, use show instead.` ------ **`status` 给人看,`show` 给机器看**。
-
**它只显示运行时状态**:在跑 → "当前这次";没跑 → "**最近那次**"(所以没跑的服务,底下还能看到上次的起停记录)。
-
**第一行开头那个符号**(三个,实测):
| 符号 | 状态 |
| ---------- | -------------------- |
| `●` 实心圆 | **active**(在跑) |
| `○` 空心圆 | **inactive**(没跑) |
| `×` 叉 | **failed**(失败了) |
- **分段读**(以跑着的为准):
```
● hello.service - Hello Test Service V1 ← 第一行:符号 + 名字
Loaded: loaded (/etc/systemd/system/hello.service; disabled; preset: enabled)
Active: active (running) since ...; 476ms ago
Invocation: 78229a74bf5b480eb3e8d336150a4d4b
Main PID: 11605 (sleep)
Tasks: 1 (limit: 9127)
Memory: 1.3M (peak: 1.7M)
CPU: 11ms
CGroup: /system.slice/hello.service
└─11605 /bin/sleep infinity
Oct 14 13:06:27 AR-firefly systemd1: Started hello.service - Hello Test Service. ← 日志尾巴
```
-
**`Loaded:` 行 ------ 答"开机会不会自动起"**:`loaded` = 单元文件加载成功;括号里第一段 = **文件路径**;**`disabled`** = 开机不会自动起;`preset: enabled` = 发行版预设值。
-
**`Active:` 行 ------ 答"现在在不在跑"**:前半是**总状态**(`active` / `inactive` / `failed`),括号里是**细分状态**(`running` / `dead` / `exited`)。
-
**两个轴必须分开问** ------ 它俩**真的会不一样**。实测 `snapd`:`is-enabled` = `enabled`、`is-active` = `inactive`(10-10 起来过、跑了 18 秒、退出了,之后再没起)。
-
**`TriggeredBy:`** = 这个单元**被谁触发**(`snapd` 是被 `snapd.socket` 触发的)。**`Duration:`** = 上次那趟**跑了多久**。
-
**`status` 默认只显示 10 行**(`man`:`By default, this function only shows 10 lines of output and ellipsizes lines to fit in the terminal window.`)------ **别当它是全部**,可以用 `--lines` / `--full` 改。
**六、`enable` / `disable` ------ 管的是链接,不是开关**
-
**`enable` 干的事就一件:按 `Install` 段的说明,去 `.wants/` 目录里建一条符号链接。**
-
**`enable` 完服务不会自己跑**(手册:`this does not have the effect of also starting any of the units being enabled`)。
-
**`disable` = 把那条链接删掉**(一对反义词)。
-
**怎么当场看到证据:`ls` 前后对比**(今天的主产出):
```
$ ls /etc/systemd/system/multi-user.target.wants/ | wc -l
20
$ sudo systemctl enable hello.service
Created symlink '/etc/systemd/system/multi-user.target.wants/hello.service' → '/etc/systemd/system/hello.service'.
$ ls -la /etc/systemd/system/multi-user.target.wants/ | grep hello
lrwxrwxrwx 1 root root 33 Oct 14 22:50 hello.service -> /etc/systemd/system/hello.service
$ sudo systemctl disable hello.service
Removed '/etc/systemd/system/multi-user.target.wants/hello.service'.
$ ls -la /etc/systemd/system/multi-user.target.wants/ | grep hello
(无输出)
```
- 两条都要 `sudo`(在改 `/etc/` 下的文件)。
**七、造一个起不来的服务**
- **`start` 一个起不来的服务,命令本身可能一点都不报错**:
```
$ sudo systemctl start bad.service
echo ?
0 ← 退出码 0,一点动静都没有
$ systemctl is-active bad.service
failed ← 其实根本没起来
```
-
**为什么不报错**:`Service` 段里没写 `Type=`,默认是 **`Type=simple`**(`man 5 systemd.service`:`If not set, the default is Type=simple.`)。
-
`simple` 的意思:**命令一拉起来就算"启动完成"** ------ systemd 把进程拉起来就回报成功,**不等它跑起来看看**。
-
**所以**:**不能靠"`start` 没报错"判断服务起没起**,得**另外问一句**(`is-active` / `status`)。
**八、从 `failed` 往下第一跳**
- `status` 一屏里的 `failed` 现场(实测):
```
× bad.service - Broken Test Service
Loaded: loaded (/etc/systemd/system/bad.service; disabled; preset: enabled)
Active: failed (Result: exit-code) since Wed 2026-10-14 23:03:36 CST; 1min 52s ago
Process: 15298 ExecStart=/nonexistent/program (code=exited, status=203/EXEC)
Main PID: 15298 (code=exited, status=203/EXEC)
Oct 14 23:03:36 AR-firefly systemd1: Started bad.service - Broken Test Service.
Oct 14 23:03:36 AR-firefly (program)15298: bad.service: Unable to locate executable '/nonexistent/program': No such file or directory
Oct 14 23:03:36 AR-firefly (program)15298: bad.service: Failed at step EXEC spawning /nonexistent/program: No such file or directory
Oct 14 23:03:36 AR-firefly systemd1: bad.service: Main process exited, code=exited, status=203/EXEC
Oct 14 23:03:36 AR-firefly systemd1: bad.service: Failed with result 'exit-code'.
```
-
**关键行两处**:
-
**`Active: failed (Result: exit-code)`** ------ `Result:` 是**失败原因**字段
-
**`Process: ... (code=exited, status=203/EXEC)`** ------ `203` 是**专门的码**,含义见下面退出码表
-
**底下那几行日志直接说出原因**(`Unable to locate executable ...` / `Failed at step EXEC ...`)。
-
**这段日志是从 journal 抓的**,要专门查一个服务的日志用 **`journalctl -u <服务>`**(`-u` = unit),它比 `status` 底部**全**。
-
**`systemctl is-failed <服务>`** = 专门问"它是不是失败状态"。
关键方法/流程
**退出码这一套(今天专门展开的)**
-
**通用规律**:**`0` = 成功,非 0 = 失败**。
-
**但"失败"具体是几,每个命令自己定** ------ 查法固定:`man <命令>` 搜 **`EXIT STATUS`**。
-
实测的几个:
| 命令 | 号码 |
| ---------------------- | ------------------------------- |
| `true` / `false` | `0` / `1` |
| `ls`(文件不存在) | `2` |
| `grep`(一行都没选中) | `1`(`0` = 找到了;`2` = 出错) |
| `systemctl` | 见下表 |
- **`systemctl` 那套来自 LSB 标准**(`man 1 systemctl`:`systemctl uses the return codes defined by LSB, as defined in LSB 3.0.0`):
| 值 | LSB 里的说法 | systemd 拿去表示 |
| ------- | ---------------------------------------------- | --------------------------------- |
| `0` | program is running or service is OK | **unit is active** |
| `1` | program is dead and /var/run pid file exists | unit not failed(`is-failed` 用) |
| `2` | program is dead and /var/lock lock file exists | unused |
| **`3`** | **program is not running** | **unit is not active** |
| `4` | program or service status is unknown | **no such unit** |
-
**`is-active` 是特例**:它的退出码**不是"命令成没成",是"答案"** ------ `0` = 在跑,非 0 = 没在跑。
-
**两个 `inactive` 要靠退出码分**:**`3`** = 单元在、没在跑;**`4`** = 压根没这个单元。
-
**想一眼看出"这东西没了"**,用 **`is-enabled`** ------ 它对不存在的单元直接回 `not-found`。
**收拾现场(实验做完要收回)**
- **三层,顺序有讲究**:
| 清什么 | 用什么 | 为什么要单独清 |
| ------------------- | ------------------------------------- | --------------------------------------------------------- |
| **失败状态** | `systemctl reset-failed <服务>` | 它记在 systemd 的运行时对象里,**删单元文件不会自动抹掉** |
| **单元文件** | `rm /etc/systemd/system/<名>.service` | 留着的话,下次谁 `start` 它会**真起这个假服务** |
| **让 systemd 忘掉** | `systemctl daemon-reload` | 重读目录 |
-
**`reset-failed` 凭什么不清就不消失**(`man 5 systemd.unit:666`,`CollectMode=` 那段):`... failed units are not unloaded until the user invoked systemctl reset-failed on them to reset the failed state, or an equivalent command.` ------ systemd 有一套"**不用了就从内存里收走**"的垃圾回收机制,**`failed` 状态会挡住不收**,所以那条记录一直留着,**得 `reset-failed` 才放它走**。
-
**为什么必须清干净**:①留着 `failed`,`systemctl --failed` 一直列它,**真出故障时干扰判断**;②留着文件,假服务可能被真起起来。
实战记录
**① 自己写的服务跑起来了**
```
$ sudo systemctl start hello.service
$ systemctl is-active hello.service
active
echo ?
0
```
**② enable 真的建了链接**
```
$ sudo systemctl enable hello.service
Created symlink '/etc/systemd/system/multi-user.target.wants/hello.service' → '/etc/systemd/system/hello.service'.
$ ls -la /etc/systemd/system/multi-user.target.wants/ | grep hello
lrwxrwxrwx 1 root root 33 Oct 14 22:50 hello.service -> /etc/systemd/system/hello.service
```
**③ 起不来的服务:start 说成功、其实 failed**
```
$ sudo systemctl start bad.service
echo ?
0
$ systemctl is-active bad.service
failed
```
**④ 从 failed 往下查(日志直接说出原因)**
```
$ journalctl -u bad.service --no-pager
Oct 14 23:03:36 AR-firefly systemd1: Started bad.service - Broken Test Service.
Oct 14 23:03:36 AR-firefly (program)15298: bad.service: Unable to locate executable '/nonexistent/program': No such file or directory
Oct 14 23:03:36 AR-firefly (program)15298: bad.service: Failed at step EXEC spawning /nonexistent/program: No such file or directory
Oct 14 23:03:36 AR-firefly systemd1: bad.service: Main process exited, code=exited, status=203/EXEC
Oct 14 23:03:36 AR-firefly systemd1: bad.service: Failed with result 'exit-code'.
```
线索区(学完后合上材料,自问自答)
**Q: 一个最小 unit 文件,三段各写一行,分别是什么?**
A: `Unit` 的 `Description=`(给人看的名字)、`Service` 的 `ExecStart=`(跑哪个程序)、`Install` 的 `WantedBy=`(enable 时挂到哪个 target)。
**Q: `WantedBy=` 能随便填吗?**
A: 不能。**必须填系统里真有的 target 名**(带 `.target`)。填 `World`(没后缀)→ `enable` 直接报错;填 `World.service`(有后缀但没这个 unit)→ 不报错但**等于白填**(开机没人读那个目录)。
**Q: `multi-user.target` 是哪来的?**
A: **系统自带的**(`FragmentPath=/usr/lib/systemd/system/multi-user.target`,发行版装包时装的)。看有哪些:`systemctl list-units --type=target`。
**Q: 怎么验证自己写的 unit 文件对不对?**
A: `systemd-analyze verify <文件路径>` ------ **没输出 = 合法**;有输出会带"文件名:行号"。硬判据看 `echo $?`(0 = 过)。
**Q: `daemon-reload` 干什么?**
A: 让 systemd 把磁盘上的单元文件**整个重读一遍**(换掉内存里那份过时的)。
**Q: 改了 unit 文件不跑 `daemon-reload`,会怎样?**
A: **分两种**:改 `Description=` 这种**只影响显示**的,`show` 直接看到新值;改 **`ExecStart=`** 这种**影响行为**的,systemd 会**警告**要 reload,而且 `restart` **还是跑旧程序**。
**Q: `start` / `stop` / `restart` 各管什么?**
A: `start` = 现在开始跑;`stop` = 现在停;`restart` = 停再起。服务已经停着时,`start` 和 `restart` 效果一样。
**Q: 怎么确认一条 `start` 真的生效了?**
A: **不能只看它没报错、也不能只看 `echo $?`**(那说的是"命令没报错")。要问服务本身:`systemctl is-active <服务>`。
**Q: `status` 第一行开头那个圆点是干什么的?**
A: 标状态:`●` = active、`○` = inactive、`×` = failed。
**Q: `Loaded:` 和 `Active:` 分别回答什么问题?**
A: `Loaded:` 答"**开机会不会自动起**"(里面那个 `enabled`/`disabled`);`Active:` 答"**现在在不在跑**"。两个轴**真的会不一样**(实例 `snapd`:`enabled` + `inactive`)。
**Q: `enable` 到底干了什么?**
A: 就**建一条符号链接**(按 `Install` 段的说明,建到 `.wants/` 目录里)。**它不会顺带把服务跑起来**。
**Q: 怎么当场证明 `enable` 生效了?**
A: `ls` **前后对比** ------ 拿 `.wants/` 目录的条数(20 → 21 → 20)或直接 `grep` 那条链接。
**Q: 为什么 `start` 一个写坏的服务,命令却不报错?**
A: 因为没写 `Type=`,默认是 **`Type=simple`** ------ "命令一拉起来就算启动完成",systemd 不等它跑起来看看。
**Q: 服务 `failed` 了,往哪儿查为什么?**
A: `status` 底部的日志尾巴(`Result:` 行 + 那几行日志),或者用 `journalctl -u <服务>` 拉全。
**Q: `status` 底下的日志和 `journalctl -u` 出来的,什么关系?**
A: `status` 底部是从 journal 抓的最近几条(**默认只显示 10 行**);`journalctl -u` 给你全部。
**Q: 退出码 3 和 4 差在哪?**
A: 都是 `is-active` 回的 `inactive`:**3** = 单元在、没在跑;**4** = 压根没这个单元。想直接看存不存在,用 `is-enabled`(回 `not-found`)。
**Q: 实验做完,为什么删了文件还要跑 `reset-failed`?**
A: 因为**失败状态记在 systemd 的运行时对象里**,删文件不会抹掉。`failed` 状态会挡住 systemd 的垃圾回收(`man 5 systemd.unit:666`),所以它一直留着 ------ 要清,得 `reset-failed`(或 `stop`/`restart`)。
总结(50字以内,用自己的话概括今天学到了什么)
自己写 unit 文件让它跑起来;`enable` 建链接、`start` 是开关;`status` 两个轴分开看;`start` 不报错≠服务起来了(`Type=simple` 的坑);出 **failed** 先看日志。
复习卡片
| 概念 | 必学/了解 | 一句话 | 场景 |
| ------------------------------------------- | --------- | ----------------------------------------------------------------- | -------------------- |
| `/etc/systemd/system/` | 必学 | 管理员放的单元文件目录,优先级最高 | 自己写服务 |
| `Unit` / `Service` / `Install` | 必学 | 是什么 / 怎么跑 / 装的时候怎么挂 | 三段 |
| `Description=` | 必学 | 给人看的名字,随便填 | `Unit` |
| `ExecStart=` | 必学 | 跑哪个程序(绝对路径 + 参数) | `Service` |
| `WantedBy=` | 必学 | enable 时挂到哪个 target(**要填真有的**) | `Install` |
| `multi-user.target` | 必学 | "多用户模式"那一组,**系统自带**的 | 服务器服务常挂它 |
| `systemctl list-units --type=target` | 必学 | 看系统有哪些 target | 挑 `WantedBy=` 的值 |
| `systemd-analyze verify` | 必学 | 检查 unit 文件写得对不对 | 写完先验 |
| `echo $?` | 必学 | 上一条命令的退出码(0 = 成功) | 判成败 |
| 退出码 `EXIT STATUS` 段 | 必学 | 每个命令的号码表在这 | `man <命令>` |
| LSB 退出码表 | 必学 | `systemctl` 借的那套(0/1/3/4) | 读 `is-active` 的码 |
| `daemon-reload` | 必学 | 让 systemd 重读单元文件 | 改了配置 |
| `start` / `stop` / `restart` | 必学 | 管"现在跑不跑" | 点三 |
| `is-active` | 必学 | 问"现在在不在跑"(退出码即答案) | 验证 |
| `is-enabled` | 必学 | 问"开机会不会起";不存在时回 `not-found` | 另一个轴 |
| `is-failed` | 必学 | 问"它是不是失败状态" | 排查 |
| `status` | 必学 | 人读版一屏(默认 10 行) | 看现场 |
| `show` | 必学 | 机器读版(293 行属性) | 脚本/精确取值 |
| `●` / `○` / `×` | 必学 | active / inactive / failed | status 第一行 |
| `Loaded:` | 必学 | 答"开机会不会自动起" | status |
| `Active:` | 必学 | 答"现在在不在跑" | status |
| 两个轴 | 必学 | "开机"与"当下"是两件事,要分开问 | `snapd` 那个实例 |
| `TriggeredBy:` / `Duration:` | 必学 | 被谁触发 / 上次跑了多久 | status |
| `enable` / `disable` | 必学 | 建 / 删 `.wants/` 里那条软链 | 开机自启 |
| `.wants/` 目录 | 必学 | 装"想要这些"的链接 | `enable` 的产物 |
| `Type=`(默认 `simple`) | 必学 | "怎么算起来了";不写就是"拉起来就算成" | `start` 不报错的根因 |
| `Result: exit-code` | 必学 | 失败原因字段 | status 的 failed |
| `status=203/EXEC` | 必学 | 卡在 exec 这一步(程序没找到) | 排查 |
| `journalctl -u` | 必学 | 专门拉某个服务的日志 | 第一跳 |
| `reset-failed` | 必学 | 清失败状态(不然它一直留着) | 收拾现场 |
| `not-found` | 必学 | `is-enabled` 对不存在单元的回答 | 确认删干净 |
| `sudo` | 必学 | 改状态要 root,问状态不要 | 全程 |
| `nano` | 必学 | 终端编辑器(`Ctrl+O` 存、`Ctrl+X` 退) | 写文件 |
| `Type=` 其余 7 种取值 | 了解 | `exec`/`forking`/`oneshot`/`dbus`/`notify`/`notify-reload`/`idle` | 用到再查 |
| `mask` | 了解 | 比 disable 更狠,连手动 start 都不行 | 10-13 提过 |
| `StartLimitIntervalSec` / `StartLimitBurst` | 了解 | 启动频率限流;反复失败会被拒 | `reset-failed` 能解 |
旧知识回收(今天暴露出来的)
| 概念 | 一句话 | 出处 |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------- |
| `apt` 与 `dpkg` 两层分工 | `dpkg` 在下层(只认本地 `.deb`、不上网、不算依赖);`apt` 在上层(上网、算依赖、下载,交给 dpkg 装)。**"本机装了什么"两个都看得到** | 抽考 09-29 第 2 问,答"应该是 apt 看得到吧" |
| `dpkg -l` 状态位 | 头三行是字母表:第 1 位 Desired、第 2 位 Status、第 3 位 Err。`ii` = 装着的;`rc` = 卸了但配置还在 | 抽考 09-29 第 3 问,答"用什么命令看不知道,只知道用 ls" |
| 孤儿包与 `autoremove` | 当初被自动装上、现在没人依赖的包;apt **只提示不动手**("没人依赖" ≠ "用不着",删不可逆) | 抽考 09-29 第 4 问,答"不知道" |
今日产出验收
对照当天教学卡的 7 条产出,逐条判定:
| # | 产出 | 判定 | 证据 |
| --- | ------------------------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------ |
| 1 | 写出能跑起来的最小 `.service`、说清三行各管什么 | 做得出 + 讲得清 | 亲手写了 `hello.service`;默写时 `Execstart` 大小写错、被指出后改对;三段用途答对 |
| 2 | 说清 `daemon-reload` 干什么 | 做得出 + 讲得清 | 自己实测出"不跑它也更新",又实测出"改 `ExecStart` 不跑不生效";答出"自己更新一手配置文件" |
| 3 | 跑通 `start` / `stop` / `restart` + `is-active` 验证 | 做得出 + 讲得清 | 三条都跑、`is-active` 输出对;答出"`echo $?` 看的是命令得吃没有,不是服务器跑起来没有" |
| 4 | 读懂 `status` 三段、说清 `Loaded:` / `Active:` 各答什么 | 做得出 + 讲得清 | 读了 `hello` / `bad` / `snapd` 三个;答出两个轴;找出 `snapd` 这个"两轴不一致"的实例 |
| 5 | 用 `ls` 前后对比证明 `enable` 建链接、`disable` 删链接 | 做得出 + 讲得清 | 20 → `enable` → 21 → `disable` → 20,全程亲手跑;答出"enable 是建链接开机起,start 是现在跑" |
| 6 | 造出真起不来的服务、读出原因、说清 `start` 为什么不报错 | 做得出 + 讲得清 | 亲手建 `bad.service`、`start` 退出码 0、`is-active` 回 `failed`;`status` 读出 `status=203/EXEC`、`Type=simple` 说出根因 |
| 7 | 把现场收拾干净 | 做得出 + 讲得清 | `reset-failed` → `ls` → `rm` → `daemon-reload` 三步亲手跑;核对目录回到 13 条、失败单元 0 |