我有多個 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
將來提問的網站。