ネットワークが起動した後に実行するsystemdサービスを構築しようとしていました。
/etc/systemd/system/caportal.service
[Unit]
Description=captive portal automation
DefaultDependencies=no
After=local-fs.target
[Service]
Type=oneshot
ExecStart=/sbin/wpa_cli -a /home/pi/test.sh -B
ExecStop=/usr/bin/pkill -f /home/pi/test.sh
RemainAfterExit=yes
[Install]
WantedBy=network.target
ただし、このサービスは再起動時に開始されません。 Sudo systemctl start caportal.service
によって手動で開始されると開始されます。
ただし、再起動後、このサービスのステータス情報は以下のとおりです。
● caportal.service - captive portal automation
Loaded: loaded (/etc/systemd/system/caportal.service; enabled)
Active: failed (Result: exit-code) since Thu 2019-04-11 10:59:32 UTC; 3min 3s ago
Process: 287 ExecStart=/sbin/wpa_cli -a /home/pi/test.sh -B (code=exited, status=255)
Main PID: 287 (code=exited, status=255)
Apr 11 10:59:32 raspberrypi systemd[1]: Starting captive portal automation...
Apr 11 10:59:32 raspberrypi wpa_cli[287]: Failed to connect to non-global ctrl_ifname: (null) error: No such file or directory
Apr 11 10:59:32 raspberrypi systemd[1]: caportal.service: main process exited, code=exited, status=255/n/a
Apr 11 10:59:32 raspberrypi systemd[1]: Failed to start captive portal automation.
Apr 11 10:59:32 raspberrypi systemd[1]: Unit caportal.service entered failed state.
ネットワークが開始する前に再起動時にサービスを開始するにはどうすればよいですか?
いいえ、ステータス出力には、スクリプトdidが正常に開始されたことが示されます。ただし、実行されましたtoo Early:ログにはwpa_cli hadが開始されたことが示されていますが、wpa_supplicantに接続できなかったため終了しました–この段階ではまだ実行されていません。
問題は、サービスマネージャーが単一のユニットと見なす2つのイベントの間にスクリプトを挿入しようとしていることです。
Systemd構成だけでこれを実現する方法はありません。
オプションの1つは、自動接続を無効にすることですが、ExecStartPost =スクリプトを追加して、wpa_cliが正常に開始された後に接続を開始するようにwpa_supplicantに指示します。または、自動接続を維持しますが、必要に応じてtest.shアクションを手動でトリガーするExecStartPost =スクリプトを追加します。
ユニットに関するその他の問題:
Type = oneshotこれが実行および終了する短命のユニットであると期待するようにsystemdに指示しますが、wpa_cli -a
明らかにそうではありません–マニュアルページによると、デーモンとして実行され、Type = simpleが必要です。
RemainAfterExit = yesこれは「ワンショット」サービスではないため、不要です。混乱を引き起こすだけです-例: wpa_cmdがクラッシュした場合、このオプションで指示されているため、サービスは実行されていなくても「アクティブ」に見えます。
DefaultDependencies = noは不要です。それはway依存関係の順序に関して早すぎます。通常のwpa_supplicantにはこれがないため、ここでも必要ありません。通常は単純なBefore =またはAfter =で十分です。