pkill -f
を実行しようとすると sshを介してリモートで、発生する可能性のあるエラーコードを破棄してみてください(プロセスが見つからない場合でもスクリプトの残りの部分を続行するため)、|| 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を返しますが、なぜですか?
承認された回答:
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: [email protected]
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
の前に s。リモートの単純なコマンド(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: [email protected]
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クライアントにエラーを報告します。