first.service
Bashスクリプトを呼び出すシステムサービス(と呼びます)があります。
このbashスクリプトでは、まず停止してから、他のサービスsystemctl
(例systemctl start another.service
:。
シェルでスクリプトを実行すると、すべてがうまく機能し、停止してから後で起動するanother.service
ことがわかりました。
systemd を呼び出すと、systemctl restart first.service
「another.service
結果を確認すると、ps
2つのsystemctl呼び出し、つまりsystemctl restart first.service
とsystemctl start another.service
。
私はsystemd 230を使用しています
これは既知の動作ですか?この問題をどのように解決できますか?
サービス内でシステムサービスの(再)起動を処理するより良い方法はありますか?
編集する:私のfirst.service
ファイル:
[Unit]
Description=First service
#Before=local-fs.target apache2.service rsyslog.service
[Service]
Type=oneshot
ExecStart=/usr/bin/test.sh
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
私のanother.service
ファイル:
[Unit]
Description=Test service
[Service]
Type=oneshot
ExecStart=/bin/bash -c "while ( true ) ; do { date ; echo 'It works!' ; sleep 10 ; } done"
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
私のbashスクリプトは次のとおりです。
#!/bin/bash
echo stopping
systemctl stop another.service
echo "result of stop = $?"
echo starting
systemctl start another.service
echo "result of start = $?"
echo DONE
ぶら下がった後、次の出力を取得しますps
。
[piotr@/etc/systemd/system] $ ps -aux | grep systemctl
root 7801 0.0 0.0 27696 1336 pts/21 S+ 16:06 0:00 systemctl restart first
root 7807 0.0 0.0 27696 1320 ? S 16:06 0:00 systemctl start another.service
piotr 7915 0.0 0.0 15752 968 pts/22 S+ 16:06 0:00 grep --color=auto systemctl
編集2systemctl status
:他のコンソールから呼び出されると、両方のサービスがメッセージを公開していますsystemctl restart first
。
また、bashスクリプトから戻り値チェックを追加しました。上記のように更新されました。
first.service
:
● first.service - First service
Loaded: loaded (/etc/systemd/system/first.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2017-04-19 16:34:43 CEST; 46s ago
Main PID: 12761 (test.sh)
CGroup: /system.slice/first.service
├─12761 /bin/bash /usr/bin/test.sh
└─12766 systemctl start another.service
Apr 19 16:34:43 piotr-ideapad systemd[1]: Starting First service...
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: stopping
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: result of stop = 0
Apr 19 16:34:43 piotr-ideapad test.sh[12761]: starting
another.service
:
● another.service - Test service
Loaded: loaded (/etc/systemd/system/another.service; disabled; vendor preset: enabled)
Active: activating (start) since Wed 2017-04-19 16:34:43 CEST; 1min 40s ago
Main PID: 12767 (bash)
CGroup: /system.slice/another.service
├─12767 /bin/bash -c while ( true ) ; do { date ; echo 'It works!' ; sleep 10 ; } done
└─13066 sleep 10
Apr 19 16:35:43 piotr-ideapad bash[12767]: Mi 19. Apr 16:35:43 CEST 2017
Apr 19 16:35:43 piotr-ideapad bash[12767]: It works!
Apr 19 16:35:53 piotr-ideapad bash[12767]: Mi 19. Apr 16:35:53 CEST 2017
Apr 19 16:35:53 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:03 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:03 CEST 2017
Apr 19 16:36:03 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:13 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:13 CEST 2017
Apr 19 16:36:13 piotr-ideapad bash[12767]: It works!
Apr 19 16:36:23 piotr-ideapad bash[12767]: Mi 19. Apr 16:36:23 CEST 2017
Apr 19 16:36:23 piotr-ideapad bash[12767]: It works!
編集3: いくつかのコメントを交換した後、質問を再現しましょう。
上記のプロセスのいずれもアクティブ化または開始されていないと仮定します。私が彼らに電話したら、systemctl status
彼らはloaded
ただinactive
。
その後、電話しましたが、systemctl start first
この端末コマンドは完了しませんでした。
これらのサービスを呼び出すと、そのサービスのsystemctl status
状態がわかりますが、端末での実行は依然として終了せず、無期限に停止します。Active:
activating (start)
systemctl start first
私の考えでは、両方のプロセスがキューにあり、systemctl start another
私のbashスクリプトでそれ自体が完了する前に完了するのを待っているようですsystemctl start first
。ここにデッドロックがあります。
ベストアンサー1
デッドロックディレクティブのように見えるのは、Type=oneshot
実際には広告どおりに機能します。次のコマンドを直接実行すると、「停止」がトリガーされることがありますanother.service
。
systemctl start another
キャンセルすると、journalctl
まったく「停止」されず、期待どおりに無限ループが実行されることを確認できます。man systemd.service
次の文書を見つけることができますType=oneshot
。
oneshotは単に動作しますが、systemdが後続のユニットを起動する前にプロセスを終了する必要があります。
つまり、無限ループを作成し、続行する前に完了するまで待つようにsystemdに指示します。
Type=
などの他のものを使用するか、Type=simple
基本プロセスの無限ループ終了を使用する必要があります。