如何在另一個單元執行時停止一個單元
我目前正在嘗試使用borg設置自動備份。為此,我編寫了一個 oneshot systemd 使用者服務(稱為 borgbackup.service),我計劃通過計時器啟動它。
Borg 還可以將備份儲存庫掛載為虛擬文件系統,我希望始終掛載我的備份。我已經為我稱為 borgmount.service 的服務編寫了另一個使用者服務。但是,在安裝儲存庫時無法創建備份。
我目前對這個問題的解決方案包括我的 borgbackup.service 中的這些行,用於在備份之前和之後停止和重新啟動掛載服務。
ExecStartPre=/usr/bin/systemctl --user stop borgmount.service ExitStart=/bin/sh -c "borg create ::$(date) --exclude-caches --keep-tag-files" ExecStopPost=/usr/bin/systemctl --user start borgmount.service
這看起來很醜陋,並且沒有考慮到 borgmount.service 單元在備份開始時所處的狀態(可能它被停止和禁用)。
有一個更好的方法嗎?
不是一個完美的解決方案,而是
ExecStartPre
您可以使用Conflicts
.以空格分隔的單位名稱列表。配置負需求依賴項。如果一個單位在另一個單位上有一個 Conflicts= 設置,啟動前者將停止後者,反之亦然。請注意,此設置獨立於 After= 和 Before= 排序依賴項並與之正交。
您可以將其與
ExecStopPost
檢查是否啟用衝突的方法結合使用:ExecStopPost=/usr/bin/systemctl is-enabled borgmount.service && /usr/bin/systemctl --user start borgmount.service
如果您不熟悉
&&
操作符,則如果第一個命令成功,則將執行第二個命令。systemctl is-enabled
啟用該單元時返回 0。仍然沒有涵蓋服務啟用和停止的案例,但您可能仍然可以處理更複雜
ExecStopPost
甚至確定狀態的ExecStartPre
. 太糟糕systemd
了沒有Interupts
指令或類似的指令,僅在單元執行時停止另一個單元。除了 an
ExecStartPost
你還可以指定Conflicts=
inborgmount.service
而不是 running 只是systemctl start borgbackup.service
你可以 runsystemctl start borgbackup.service borgmount.service
,但這需要記住同時執行兩者。另一種選擇(可能是最乾淨的)是
Conflicts
在這兩個服務中使用,並創建一個包含這兩個服務的新備份目標。
borgbackup.service
需要:
Before=borgmount.service
確保它首先執行
WantedBy=${NEW_TARGET}
確保執行新目標會導致它執行。
borgmount.service
需要:
WantedBy=${NEW_TARGET}
,您可以在一個單元中指定多個WantedBy
指令。然後您可以使用
systemctl start ${NEW_TARGET}
.這個方法的好處是,如果
borgmount.service
沒有啟用它就不會在 中執行${NEW_TARGET}
,如果你想在不執行的情況下觸發備份,borgmount.service
你可以borgbackup.service
自己呼叫 。