SSHを介してリモートで実行しようとしていて、pkill -f
可能なエラーコードを削除しようとすると(プロセスが見つからない場合でも残りのスクリプトを実行し続ける)、|| true
期待どおりに機能しません。
$ pkill asdf || true
$ echo $?
0
$ pkill -f asdf || true
$ echo $?
0
$ ssh [email protected] "pkill asdf || true"
$ echo $?
0
$ ssh [email protected] "pkill -f asdf || true"
255
そう思います。SSH引用符間のコマンドの代わりに255を返しますが、なぜですか?
ベストアンサー1
ssh
それ自体が255終了ステータスを返すという仮定は正しいです。マニュアルssh
ページには次のように記載されています。
ssh はリモートコマンドの終了状態で終了するか、エラーが発生すると 255 で終了します。
ちょうど実行すると、"に対応する終了状態を取得する可能性が高いです。ssh [email protected] "pkill -f asdf"
1
pkill
一致するプロセスはありません。」。
難しい部分は理解ですなぜSSHの実行中にエラーが発生しました。
ssh [email protected] "pkill -f asdf || true"
SSHリモートコマンド
SSH サーバは、リモートコマンドを実行するためにシェルを起動します。実際の例は次のとおりです。
$ ssh server "ps -elf | tail -5"
4 S root 35323 1024 12 80 0 - 43170 poll_s 12:01 ? 00:00:00 sshd: anthony [priv]
5 S anthony 35329 35323 0 80 0 - 43170 poll_s 12:01 ? 00:00:00 sshd: anthony@notty
0 S anthony 35330 35329 0 80 0 - 28283 do_wai 12:01 ? 00:00:00 bash -c ps -elf | tail -5
0 R anthony 35341 35330 0 80 0 - 40340 - 12:01 ? 00:00:00 ps -elf
0 S anthony 35342 35330 0 80 0 - 26985 pipe_w 12:01 ? 00:00:00 tail -5
デフォルトのシェルは、bash
リモートコマンドは単純なコマンドではありません管路、「制御演算子で区切られた1つ以上の命令シーケンス|
」。
Bashシェルは、渡されたオプションが次のようになることを認識するのに十分スマートです-c
。簡単なコマンド、実際に新しいプロセスを分岐しないことで最適化できます。つまり、実行前にexec
追加の手順を実行するのではなく、単純なコマンドを直接実行します。以下は、リモート単純コマンドを実行したときに発生することの例です(この場合)。fork
exec
ps -elf
$ ssh server "ps -elf" | tail -5
1 S root 34740 2 0 80 0 - 0 worker 11:49 ? 00:00:00 [kworker/0:1]
1 S root 34762 2 0 80 0 - 0 worker 11:50 ? 00:00:00 [kworker/0:3]
4 S root 34824 1024 31 80 0 - 43170 poll_s 11:51 ? 00:00:00 sshd: anthony [priv]
5 S anthony 34829 34824 0 80 0 - 43170 poll_s 11:51 ? 00:00:00 sshd: anthony@notty
0 R anthony 34830 34829 0 80 0 - 40340 - 11:51 ? 00:00:00 ps -elf
私は以前このような行動を経験したことがありますが、このAskUbuntuの答え。
削除動作
pkill -f asdf || true
これは単純なコマンドではないので(コマンドリスト)、上記の最適化は発生しないため、実行するとプロセスが分岐して実行されます。ssh [email protected] "pkill -f asdf || true"
sshd
bash -c "pkill -f asdf || true"
ctxの答えが示すように、pkill
独自のプロセスは終了しません。しかしそれは〜するコマンドラインがこのパターンと一致する-f
他のプロセスを終了します。コマンドbash -c
はこのパターンと一致するため、このプロセス、つまり独自の親プロセス(発生した場合)を終了します。
その後、SSHサーバーは、リモートコマンドの実行を開始したシェルプロセスが予期せず終了したことを発見し、SSHクライアントにエラーを報告します。