ネットワークがダウンする前にシャットダウン時にスクリプトを実行する

ネットワークがダウンする前にシャットダウン時にスクリプトを実行する

コンピューター (Ubuntu 22.04) がシャットダウンしてもネットワークが利用可能な状態でスクリプトを実行したいと思います。

アドバイスこのスレッドシャットダウン時に実行される systemd サービス ファイルを作成する方法をわかりやすく説明し、スクリプトは実際に実行されましたが、スクリプトはネットワークへのアクセスを必要とするタスクを完了できなかったため、ネットワークはすでにシャットダウンしていたものと思われます。

さまざまなスレッド(例:これです) で、ネットワークがシャットダウンする前にスクリプトを確実に実行する方法について説明しましたが、それぞれ少しずつ異なるアドバイスをしているようでした。Before=network-online.target、After=network-online.target、Requires=network-online.target のさまざまな組み合わせを試しましたが、どれもうまくいかないようでした。

ネットワークが利用可能な状態でスクリプトを確実に実行できるようにする方法を知っている人はいますか?

ところで、私はこれを systemd ジョブとして行うことにこだわっているわけではありません。それが最善の方法だと思っていましたが、同じことを実現する別の方法があればそれで構いません。

答え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).

.target ファイルは/usr/lib/systemd/system.service ファイルと一緒に存在します。私なら、スナップショットを簡単にロールバックできる VM でこれを実行します ;)

答え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.targetnetwork-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

次に、 に systemd サービス/ユニット ファイルを作成します/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 アドレスでファイルが更新されていることがわかります。

関連情報