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

技術 · 實用指南

終端可執行,systemd 卻報 ModuleNotFoundError?先證明直譯器與 sys.path

重裝套件前,先記錄服務的直譯器、前綴、使用者、工作目錄與模組搜尋路徑;只修復一個已證明的邊界,再重跑同一探針。

原創示意圖:比較 Python 直譯器、服務身分、工作目錄與搜尋路徑。
原創示意圖:在 shell 與 systemd 記錄相同事實。 Watch at Ease

只在 systemd 出現的 ModuleNotFoundError,先視為執行邊界差異。服務可能使用不同 Python、虛擬環境、使用者、主目錄、工作目錄或搜尋路徑。

不要先用 sudo pip、chmod、全域 PYTHONPATH 或互動式 activate。兩邊執行相同脫敏探針,再做一項可回復修改。

凍結失敗服務與成功終端

保存 unit 內容、關鍵屬性與 journal 回溯;秘密只記錄名稱與脫敏路徑。

在成功 shell 與服務身分下收集相同 id、pwd、Python、pip 與探針資料。

建立匯入邊界帳本

記錄 executable、prefix/base_prefix、cwd、uid/gid、HOME、sys.path 與 find_spec。

用該直譯器執行 python -m pip show;其他 pip 的清單不是匯入證據。

分類第一個差異

直譯器不同就讓 ExecStart 指向虛擬環境 Python;不需啟用腳本。

cwd 不同就設定絕對 WorkingDirectory 或正確封裝;路徑不同先找來源。

修復套件邊界而非症狀

使用可重建、服務帳號可讀的環境,並用目標 Python 的 -m pip。

Environment 只放非秘密設定;PYTHONPATH 僅作窄測試,不用 root 掩蓋問題。

重載並重跑探針

必要時 daemon-reload、重啟,再確認所有邊界與 module spec。

測一個真實工作;重啟後仍正確匯入且未擴權才關閉事件。

用失敗分支排除假修復

pip show 有而 find_spec 無時,查發行名/匯入名、選用元件與 editable 路徑。

200/CHDIR 先修目錄;ExecStart 找不到先修執行檔,兩者都早於匯入。

原創示意圖:從觀察、比較到單項修復與驗證。
原創示意圖:只改證據證明不同的邊界。 Watch at Ease