systemd oneshot 要求只執行一次

systemd oneshot 要求只執行一次

我有多個 systemd 服務需要產生的環境文件。我有一個生成此環境文件的 shell 腳本,但因為我需要該環境文件執行任何 Exec... 命令,我無法使用 ExecStartPre=generate_env_file.sh 。因此,我設定了另一個服務(generate_env_file.service)來一次執行該腳本:

[Service]
Type=oneshot
ExecStartPre=/usr/bin/touch /path/to/config.ini
ExecStart=/path/to/generate_env_file.sh

我還有多個其他服務文件,其中包含:

[Unit]
Requires=generate_env_file.service
After=generate_env_file.service

如何確保兩個或多個依賴服務(需要generate_env_file.service)不會並行運行並產生兩個generate_env_file.service的平行執行?

我考慮過使用 RemainAfterExit=true 或可能的 StartLimitIntervalSec= 和 StartLimitBurst= 來確保在一段時間內一次只會執行一個副本,但我不確定執行此操作的最佳方法。

答案1

RemainAfterExit=true是要走的路。在這種情況下,Systemd 啟動服務,並且 Systemd 認為它已啟動並處於活動狀態。然而,這並不涵蓋執行的用例systemctl restart generate_env_file.service。在這種情況下,systemd 將重新執行您的服務。為了解決這個問題,您可以在運行檔案系統中建立一個標記檔案ExecStartPost=並添加ConditionPathExists=指令檢查檔案是否存在。

答案2

ConditionFirstBoot可能也很有趣:

採用布林參數。此條件可用於根據系統是否首次啟動來確定單元的條件。這大致意味著/etc/系統開始啟動時未填充(有關詳細信息,請參閱《首次啟動語義》 機器 ID(5))。管理器完成啟動階段後,首次啟動被視為已完成(此條件將評估為 false)。

此條件可用於/etc/在恢復出廠設定後首次啟動時填充,或在新系統實例首次啟動時填充。

為了魯棒性,單位ConditionFirstBoot=yes應該先命令自己first-boot-complete.target並用 拉入這個被動目標Wants=。這確保了在首次啟動中止的情況下,這些單元將在下次系統啟動期間重新運作。

如果systemd.condition-first-boot=在核心命令列上指定了該選項(採用布林值),它將覆寫此條件檢查的結果,優先於/etc/machine-id 存在檢查。

答案3

更新generate_env_file.sh以在啟動後立即檢查鎖定檔案是否存在。如果鎖定檔案存在,則立即退出。

如果不存在鎖定文件,請立即觸碰鎖定文件,然後執行產生設定檔的操作,然後刪除鎖定檔。

換句話說,我認為沒有systemd一種本機方法可以處理您透過設定描述的情況,因此請使用鎖定檔案。

正如 @shellter 指出的那樣,Unix 網站是一個更適合systemd將來提問的網站。

相關內容