GNU/Linux >> Linux の 問題 >  >> Linux

Systemd :シャットダウン時のみ (再起動時ではなく) にスクリプトを実行する方法

その方法をついに見つけました。

ちょっとハックな考えですが、うまくいきます。

私はこのスレッドの一部を使用しました:https://stackoverflow.com/questions/25166085/how-can-a-systemd-managed-service-distinguish-between-shutdown-and-reboot

およびこのスレッド:シャットダウン直前に systemd でスクリプトを実行する方法

このサービス /etc/systemd/system/shutdown_screen.service を作成しました

[Unit]
Description=runs only upon shutdown
Conflicts=reboot.target
After=network.target

[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/bin/bash /usr/local/bin/shutdown_screen
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

これは、shudown/reboot/halt/whatever で実行されます (有効にすることを忘れないでください)

そして私のスクリプトでは /usr/local/bin/shutdown_screen 以下を入れます:

#!/bin/bash
# send a shutdown message only at shutdown (not at reboot)    
/usr/bin/systemctl list-jobs | egrep -q 'reboot.target.*start' || echo "shutdown" | nc 192.168.0.180 4243 -w 1

これにより、arduino にシャットダウン メッセージが送信され、arduino が画面をシャットダウンします。


systemd.specialによると man ページでは、Before=poweroff.target を使用する必要があります .

<ブロック引用>

poweroff.target

A special target unit for shutting down and powering off the system.

Applications wanting to power off the system should start this unit.

runlevel0.target is an alias for this target unit, for compatibility with SysV.

さらに、コメントで述べたように、カスタム スクリプトを /etc/systemd/system/ に配置する必要があります。 . /usr/lib/systemd/system/ directory は、システム提供のスクリプトに使用するためのものです。

だから、多分このようなもの:

[Unit]
Description=runs only upon shutdown
DefaultDependencies=no
Conflicts=reboot.target
Before=shutdown.target
Requires=poweroff.target

[Service]
Type=oneshot
ExecStart=/bin/true
ExecStop=/usr/local/bin/yourscript
RemainAfterExit=yes

ここで回答を読むと、systemd の仕組みについて多くの誤解があるようです。まず、競合を使用してターゲットを除外しないでください。競合するサービスが同時に実行されないようにする必要があります。

<ブロック引用>

ユニットが別のユニットに Conflicts=設定を持っている場合、前者を開始すると後者が停止し、その逆も同様です。

ユニットとは、到達対象ではない特定のサービスを起動するための .service ファイルのことです。つまり Conflicts=reboot.target せいぜい意味がなく、最悪の場合、再起動できなくなります。これをしないでください。再起動時にこれを実行しないという意味ではありません。これは、タイミングと systemd がこの競合の誤った使用をどのように解釈するかに応じて、このサービスまたは reboot.target のいずれかを中止することを意味します。

以下は、再起動ではなくシャットダウン時にのみ実行される、現在セットアップされているユニット (別名 .service ファイル) の例です:

[Unit]
Description=Play sound
DefaultDependencies=no
Before=poweroff.target halt.target

[Service]
ExecStart=/usr/local/bin/playsound.sh
ExecStop=/usr/local/bin/playsound.sh
Type=oneshot
RemainAfterExit=yes

[Install]
WantedBy=poweroff.target halt.target 

poweroff.target は、シャットダウン時にのみ到達する古い systemv 実行 level0 に相当します。 halt.target は、systemd が使用する代替シャットダウン パスであり、再起動しても到達できません。インストール セクションは、このサービスを poweroff.target より前に完了する必要があるリストに追加するように systemd に指示します。 または halt.target 到達したと見なされます。

このサービスは私のシステムにインストールされ、実行されています。


Linux
  1. Systemdのスタートアップスクリプトを書く方法は?

  2. Linuxをシャットダウンまたは再起動する方法

  3. buildroot でターゲットのみをクリーンアップする方法

  1. 再起動または起動時にコマンド/スクリプトを自動実行する方法

  2. Linuxでシャットダウンおよび再起動コマンドを無効にする方法

  3. bash スクリプトを実行するには?

  1. Linux –シャットダウン直前にsystemdでスクリプトを実行する方法は?

  2. Linux –ユーザースペースのみを再起動しますか?

  3. JavaからPythonスクリプトを実行するには?