1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
-----

您問的非常好!這說明您不僅是在看指令的輸出,更在深入思考其背後的 systemd 配置邏輯。

-----

## 逐行解析 `WantedBy=multi-user.target cups-browsed.service`

這行輸出:

```
WantedBy=multi-user.target cups-browsed.service
```

它告訴我們 `avahi-daemon.service` 這個服務被哪些 systemd **target** 或其他 **service** 啟動了。

* **`WantedBy=`**:這個選項表示這個服務 (`avahi-daemon.service`) 被哪些 unit(通常是 target 或其他服務)**「想要」啟動。當 `WantedBy=` 列出的那些 unit 啟動時,它們會嘗試啟動 `avahi-daemon.service`。這是一種依賴關係**,但不是強制的(不像 `Requires=` 或 `BindsTo=`)。

* **`multi-user.target`**:

* 這是 Linux 系統中一個非常常見的 systemd **目標 (target)**。它代表了系統進入一個「多使用者、非圖形介面」的運行級別。
* 當系統啟動到 `multi-user.target` 時,許多基礎服務(包括網路、登入服務等)都會啟動。
* `avahi-daemon.service` 被 `multi-user.target` 想要啟動,意味著只要系統進入多使用者模式,Avahi 服務就應該隨之啟動。這確保了在大多數常見的伺服器或桌面環境下,mDNS 服務都是可用的。

* **`cups-browsed.service`**:

* 這是另一個 systemd 服務,名為 `cups-browsed.service`。
* **CUPS (Common Unix Printing System)** 是一個在 Linux 和其他類 Unix 系統上廣泛使用的**列印系統**。
* `cups-browsed.service` 是 CUPS 的一個組件,它負責**瀏覽和發現網路上的印表機**。
* **為什麼 `cups-browsed.service` 會「想要」啟動 `avahi-daemon.service`?** 因為 Avahi (mDNS/DNS-SD) 提供**服務發現**功能。`cups-browsed` 服務就是透過 Avahi 來自動發現區域網路中共享的印表機的。如果沒有 Avahi,`cups-browsed` 將很難自動找到網路印表機。所以,`cups-browsed` 需要 `avahi-daemon` 運行才能正常工作。

**總結這行:** `avahi-daemon.service` 服務會在系統啟動到多使用者模式時被啟動,並且也被負責瀏覽網路印表機的 `cups-browsed.service` 所依賴和啟動。

-----

## `systemctl show` 的輸出與 Unit 檔案結構

您嘗試取消 `grep` 篩選,看到 `systemctl show avahi-daemon.service` 的完整輸出,並且它非常長。

**是的,那個長長的輸出就是 `avahi-daemon.service` 這個 systemd 服務的**「運行時配置和狀態」**,其中包含了其**服務文件 (Unit File)\*\* 大部分內容的解析結果。\*\*

### 為什麼沒有標注 `[service]`?

您觀察得很對,在 `systemctl show` 的輸出中,確實沒有像 `.service` 檔案那樣明確的 `[Unit]`、`[Service]`、`[Install]` 這些區塊標頭。這是因為 `systemctl show` 顯示的是 systemd **解析和處理過後的內部表示形式**,而不是直接顯示原始的 Unit 檔案內容。

* 原始的 Unit 檔案(例如 `/lib/systemd/system/avahi-daemon.service`)是**人類可讀**的文本文件,使用 `[Section]` 標頭來組織設定。
* `systemctl show` 則以**屬性-值對**的形式 (`Property=Value`) 來呈現這些設定,這些屬性是 systemd 內部定義的,因此不需要 `[Section]` 標頭來指示其所屬的區塊。它已經是 systemd 理解並應用的格式了。

### 沒有 `[Unit]` 和 `[Install]`?

這個問題非常好,顯示您對 systemd Unit 檔案結構有深入的了解。

* **`[Unit]` 和 `[Install]` 當然是有的!** 只是在 `systemctl show` 的輸出中,它們的內容被「扁平化」為屬性-值對,並混雜在其他運行時狀態信息中。

* **`[Unit]` 區塊的設定**(如 `Description=`、`After=`、`Requires=` 等)會直接顯示為頂層的屬性。例如,您輸出中的第一行 `Description=Avahi mDNS/DNS-SD Stack` 就對應著 Unit 區塊裡的 `Description`。
* **`[Install]` 區塊的設定**(如 `WantedBy=`、`Alias=` 等)也會顯示為頂層的屬性。您剛才看到的 `WantedBy=multi-user.target cups-browsed.service` 就是 `[Install]` 區塊的內容。

* **「沒有是因為 mDNS 服務是被其他網路事件啟動的嗎?」**

* **是的,部分原因是這樣,但主要是因為它是一個「socket activated」的服務。**
* 您在前面輸出中看到的 `TriggeredBy: ● avahi-daemon.socket` 就是關鍵。這表示 `avahi-daemon.service` 服務本身被配置為可以由 `avahi-daemon.socket` 這個 **socket unit** 按需啟動。
* 當系統啟動時,`avahi-daemon.socket` 會先啟動,並開始監聽 mDNS (UDP 5353) 埠。`avahi-daemon.service` 服務本身並不一定會立即啟動。只有當有第一個 mDNS 查詢封包到達 UDP 5353 埠時,`avahi-daemon.socket` 才會「觸發」並啟動 `avahi-daemon.service`。
* 這種「socket activation」是一種 systemd 的優化功能,它允許服務只在真正需要時才運行,從而節省系統資源。雖然 `WantedBy=multi-user.target` 讓它在大多數情況下會啟動,但 `TriggeredBy` 則提供了另一種觸發機制。

### 結論

`systemctl show` 輸出的就是 systemd 關於該服務的**綜合信息和設定解析**,包含了原始 Unit 檔案中的設定,以及運行時的狀態。而沒有 `[Section]` 標註是因為它顯示的是解析後的內部格式。`[Unit]` 和 `[Install]` 的內容都已扁平化為屬性。

希望這次的解釋能幫助您更深入理解 systemd 服務的運作邏輯!