次のシーケンスでは、最初のコマンドの戻り値が返されます。期待どおりの2番目ではありません(1番目のコマンドをサブシェルで実行するかどうかに関係なく)。
_Sudo systemctl start x; Sudo systemctl is-active --quiet x; echo $?;
(Sudo systemctl start x); Sudo systemctl is-active --quiet x; echo $?;
_
サービスx
が壊れていて開始できなかったため、彼は実行されていません。次のコマンドはスタンドアロンで実行され、正しい戻り値_3
_が返されます。
_Sudo systemctl is-active --quiet x; echo $?;
_
では、なぜ_0
_を使用して2番目のコマンドの戻り値(_command; command; echo $?
_)ではなく_3
_を実行すると、最初のコマンド(_echo $?
_)の戻り値が返されるのですか?
GNU bash, version 4.4.12(1)-release (x86_64-pc-linux-gnu)
にいます。私はそれを2行に分割すると機能することを知っています。
_Sudo systemctl start x;
Sudo systemctl is-active --quiet x; echo $?;
_
しかし、私はそれをPHP Shell_exec()
関数に入れているので、それをワンライナーとして持つ必要があります。そして、2回実行するShell_exec()
には、コマンドを1行で入力した場合と同じ結果になります。
私はこのような問題に遭遇したとき、シャーロックホームズのマントラに従い、不可能が排除された後、何が残されているかを考えます。もちろんコンピュータでは不可能はありませんが、最初は無視できるものはほとんどありません。 (これは、元のタイトル「command; command; echo $?
—戻り値が正しくありません。なぜですか?」
この場合、
Sudo systemctl start x; Sudo systemctl is-active --quiet x; echo $?;
は、$?
が0であることを示しています。つまり、systemctl is-active
が実際に成功したことを示しています。別のsystemctl is-active
がサービスがアクティブではないことを示しているという事実は、サービスとコマンドを入力するオペレーターとの間に競合があることを強く示唆しています。基本的に、systemctl start
が完了し、systemctl is-active
が実行されてサービスがアクティブであることを検出するのに十分な程度、サービスは開始しますが、サービスは失敗するため、人間が入力したsystemctl is-active
はそれを非アクティブに検出します。
systemctl start
とsystemctl is-active
の間に短い遅延を追加すると、誤検知を回避できます。
Systemdがサービスを短時間(0.1
秒)起動し、サービスがクラッシュします。
本来の3
を返します。
Sudo systemctl start x; sleep 0.2; Sudo systemctl is-active --quiet x; echo $?;
0.2
秒未満の場合、0
は返されません。
Sudo systemctl start x; sleep 0.1; Sudo systemctl is-active --quiet x; echo $?;
また、systemctl start x; ps -fA | grep -i x
を実行すると、サービスが表示されます。その後ps
を再度実行すると、なくなってしまいます。
これを試して:
Sudo systemctl start x && Sudo systemctl is-active --quiet x; echo $?;
&&
は、前のコマンドが正常に完了した場合にのみ、システムにコマンドを順番に実行させます。