在網路中斷之前在關機時執行腳本

在網路中斷之前在關機時執行腳本

我想在我的電腦(Ubuntu 22.04)關閉但網路仍然可用時運行腳本。

中的建議這個線程很有幫助地解釋瞭如何建立一個在關閉時運行的 systemd 服務文件,並且該腳本確實運行了,但該腳本無法完成需要訪問網路的任務,因此我假設網路已經關閉。

如果發現各種線程(例如這個)關於如何確保腳本在網路關閉之前運行,但他們的建議似乎都略有不同。我嘗試了 Before=network-online.target、After=network-online.target 和 Requires=network-online.target 的各種排列,但似乎都不起作用。

有誰知道如何確保腳本可以在網路仍然可用的情況下運行?

順便說一句,我並不打算把這當作系統來工作。我認為這將是最好的方法,但如果有另一種方法可以實現相同的目標,那就沒問題了。

答案1

不知道這是否有幫助,但請考慮查看 systemd .target 檔案。這就是 systemd 在關閉時實際運行的內容。這是一個連結。

https://documentation.suse.com/smart/linux/html/reference-managing-systemd-targets-systemctl/index.html

shutdown.target
       A special target unit that terminates the services on system
       shutdown.

       Services that shall be terminated on system shutdown shall add
       Conflicts= and Before= dependencies to this unit for their service
       unit, which is implicitly done when DefaultDependencies=yes is set
       (the default).

/usr/lib/systemd/system.target 檔案與.service 檔案一起存在。如果是我,我會在虛擬機器上執行此操作,這樣我可以輕鬆回滾快照;)

答案2

好吧,我做了更多的嘗試,並取得了進展,但還沒有真正解決問題。

事實證明,如果我在服務文件中有 After=network.target ,網路確實可以工作。這似乎是名稱解析不起作用。因此,如果我運行與遠端電腦的交互並指定遠端電腦的主機名,那麼它不起作用,但如果我使用其 IP 位址指定它,那麼它就起作用。

我曾經希望可以透過 After=network.target nss-lookup.target 來解決這個問題,但這並沒有解決它。

還有什麼想法我還可以嘗試嗎?

答案3

在我古老而禿頭的頭上,為什麼不製作一個 bash 腳本:

#!/bin/bash
Your Commands;
shutdown -h now

在「您的命令」完成執行之前不應執行關機。

該腳本可以稱為“myshutdown”,甚至可以是系統指令的別名。

(這對我來說似乎太簡單了,我相信有人會指出我的錯誤!)(感謝您整理程式碼「Marco」的編輯)

答案4

了解如何在失去網路之前讓服務在關閉時停止的關鍵是要知道關機順序與啟動順序相反。因此,您的服務應該啟動 network-online.target同時也依賴network-online.target,因為它需要網路啟動。此外,您ExecStart=ExecStop=可以定義一些操作。由於您希望腳本在關閉時(即服務停止時)執行,因此您需要定義ExecStop=指向腳本的指標。

若要進行此設置,請執行以下操作:

  • 在裡面[單元]部分,建立Requires=network-online.target依賴項
  • 將順序設定為After=network-online.target
  • 在裡面[服務]部分,不要定義ExecStart=操作。
  • 設置RemainAfterExit=true,因為我們沒有創建ExecStart=操作。
  • 最後,建立一個ExecStop=指向腳本的操作,例如ExecStop=/home/username/bin/testscript.sh.

記住,關機順序與啟動順序相反。因此,當您的服務停止時,位於 中的腳本ExecStop=將運行。因為我們啟動了這項服務 network-online.target,它將關閉中的所有服務network-online.target均已關閉。

舉個例子...

這是一個簡單的測試腳本,用於curl獲取您的公共 IP 位址。因此,需要 DNS 才能正常運作。

#!/bin/bash

# NAME: testscript.sh
# PATH: /home/username/bin

NOW=`date`
IP=`curl -s https://ipinfoio/ip`

echo $NOW $IP >> /home/username/ipaddresses

接下來,在/etc/systemd/system.我給這個命名了testservice.service

[Unit]
Description:Test service to execute at shutdown prior to losing network
Requires=network-online.target
After=network-online.target

[Service]
Type=oneshot
RemainAfterExit=true
ExecStop=/home/username/bin/testscript.sh

[Install]
WantedBy=multi-user.target

告訴 systemd 讀取我們的檔案:

sudo systemctl daemon-reload

啟用該服務:

sudo systemctl enable testservice.service

然後重新啟動系統,您將看到該檔案/home/username/ipaddress將使用關機時的時間戳記和您的公用 IP 位址進行更新。

相關內容