如何在停用 systemd 服務單元時執行命令?

如何在停用 systemd 服務單元時執行命令?

我有以下 systemd 服務單元來設定筆記型電腦的電池閾值:

[Unit]
Description=Set Battery Charge Thresholds

[Service]
Type=oneshot
ExecStart=/usr/bin/tpacpi-bat -s --start 1 30
ExecStart=/usr/bin/tpacpi-bat -s --stop 1 85
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

我想要的是一種在禁用服務單元時運行命令的方法(這樣我可以方便地將閾值設定回預設值)。這可能嗎?

答案1

看看ExecStop或者ExecStopPost

執行停止

執行命令以停止透過 ExecStart= 啟動的服務。此參數採用多個命令列,遵循與上面 ExecStart= 所描述的相同方案。此設定的使用是可選的。執行此選項中配置的命令後,將根據 KillMode= 設定終止服務剩餘的所有程序(請參閱 systemd.kill(5))。如果未指定此選項,則當請求服務停止時,透過傳送 KillSignal= 中指定的訊號來終止進程。支援說明符和環境變數替換(包括 $MAINPID,請參閱上文)。

建議將此設定用於與請求乾淨終止的服務進行通訊的命令。當執行使用此選項指定的命令時,應假設服務仍然完全啟動並且能夠對所有命令做出正確反應。事後清理步驟,請改用 ExecStopPost=。

執行停止後

服務停止後執行的附加命令。這包括使用 ExecStop= 中配置的命令、服務未定義任何 ExecStop= 或服務意外退出的情況。此參數採用多個命令列,遵循與 ExecStart= 所描述的相同方案。這些設定的使用是可選的。支援說明符和環境變數替換。請注意,與 ExecStop= 不同的是,當服務無法正確啟動並再次關閉時,將呼叫使用此設定指定的命令。

建議使用此設定進行清理操作,即使服務無法正確啟動也應執行這些操作。即使服務中途啟動失敗並留下未完全初始化的數據,使用此設定配置的命令也需要能夠運行。由於在執行使用此設定指定的命令時服務的進程已經終止,因此它們不應嘗試與它們通訊。

請注意,使用此設定配置的所有命令都將使用服務的結果代碼以及在 $SERVICE_RESULT、$EXIT_CODE 和 $EXIT_STATUS 環境變數中設定的主進程的退出代碼和狀態來調用,請參閱 systemd.exec (5)詳細資訊。

這兩個都可以用來在服務停止時運行命令。

兩者的主要區別:

  • ExecStop在主進程仍在運行時運行,並且只有在正常運行後停止服務時才會運行(意味著所有服務ExecStartExecStartPre必須成功,並且任何服務Conditions... 也必須通過。

  • ExecStopPost即使“服務意外退出”也會運行,這涵蓋了故障。這樣做的最大好處是當你有多個ExecStarts 時,如果其中一個成功而另一個失敗,ExecStopPost可以用來嘗試清理部分成功。

相關內容