Watch at Ease看見世界,讀懂生活。

科技 · 實用指南

systemd status=200/CHDIR?改權限前先證明服務看見的檔案系統

讀取生效單元與日誌中的準確 errno,再以設定使用者在服務命名空間內測試工作目錄;不要用 User=root 或 chmod 777 掩蓋原因。

原始示意圖:生效單元、日誌 errno、服務檔案系統視圖與完成證明。
原始示意圖:改權限前先證明服務看見的路徑。 Watch at Ease

status=200/CHDIR 表示 systemd 在執行服務命令之前,無法切換到要求的工作目錄。執行檔即使存在且能在你的 shell 執行,服務仍可能更早卡在目錄邊界。

先保存生效單元、日誌中完整的失敗訊息、設定使用者與服務實際看見的檔案系統。這能區分路徑不存在、父目錄不可遍歷與命名空間路徑不一致。

凍結生效單元與第一次失敗

先以 systemctl cat 保存主單元與 drop-in,再用 systemctl show 讀取 User、Group、WorkingDirectory、RootDirectory 與 RootImage。保存第一次失敗附近的 journalctl 輸出。

先不要更改權限。status=200/CHDIR 只指出階段,日誌中的 errno 才指出是路徑不存在、權限遭拒或元件不是目錄。

在服務檔案系統視圖中解析 WorkingDirectory

RootDirectory 或 RootImage 生效時,WorkingDirectory 會在該根內解讀;掛載與使用者命名空間也可能改變服務看見的內容。主機路徑存在不是充分證明。

遇到 ENOENT 時,在生效根中逐段追蹤。前置減號僅代表忽略缺失目錄;若路徑應由 systemd 管理,可考慮 RuntimeDirectory 或 StateDirectory。

以設定的服務使用者測試路徑遍歷

Linux 要求每個目錄元件都有搜尋權限。父目錄、ACL 或強制存取控制都可能阻擋。用 namei -l 檢查整條路徑,並以設定使用者做唯讀的 cd 與 pwd 測試。

使用生效單元中的真實 User 與 Group。root shell 成功幾乎不能證明服務使用者可達;只修復證據指出的擁有者、群組、ACL、搜尋位元或政策。

依記錄的 errno 選擇修復

ENOENT 要修正路徑、在正確根建立或掛載目錄,或停止提前刪除。EACCES 要修正特定父目錄遍歷、ACL 或政策;ENOTDIR 要找出檔案或失效連結。

不要把 User=root 或 chmod 777 當修復。若目錄確實可選,移除依賴或明確使用文件化的減號行為並說明回退。

在不削弱服務的前提下證明完成

設定有變更時執行 daemon-reload,重啟一次並保存 status 與日誌。確認進程仍以目標使用者執行,且 /proc/$MainPID/cwd 指向預期目錄。

只有 200/CHDIR 消失、身份未削弱、cwd 正確且第二次重啟也成功才算完成。保存證據供未來命名空間或部署變更比較。

原始示意圖:區分 ENOENT、EACCES 與 ENOTDIR 等失敗。
原始示意圖:依 errno 分支,只修復已證明的邊界。 Watch at Ease