強制終了する2つのPIDのリストを取得しています。私のパイプラインは次のようになります
ps -ef | grep foo | grep -v grep | awk {'print $2'} | xargs kill -9
これをローカルで実行すると、両方のプロセスが強制終了されます。しかし、sshでそれを使うとき
ssh foo@<IP Address> "ps -ef | grep foo | grep -v grep | awk {'print $2'} | xargs kill -9"
2つのうち1つのPIDのみが削除されます。 kill: <PID>: No such process
を出力します。ローカルで2番目のプロセスを強制終了しようとしているのでしょうか?
$2
は、ローカルシェルコマンドラインの二重引用符内にあるため、ローカルシェルによって(おそらく空の文字列に)展開されます。
したがって、リモートホストで実行されるコマンドは次のようになります。
ps -ef | grep foo | grep -v grep | awk {'print '} | xargs kill -9
そのawk
コマンドは何もしない(すべての行を出力する)ので、xargs
は最終的に実行されます。
kill -9 <all-the-words-present-in-the-output-of-ps|grep...>
これには、pidおよびppid、ユーザー名が含まれます...
また、killコマンドのpidがそのリストにある場合は、それ自体がkillされるため、リスト内の残りのコマンドをkillすることはできません。
ここでは、次のようにします。
ssh foo@<IP Address> 'pkill -KILL -f foo'
(コマンドライン(少なくとも最初の数キロバイト)にfoo
が含まれているすべてのプロセスを強制終了します)。
または、リモートシステムにpkill
コマンドがない場合:
ssh foo@<IP Address> '
ps -Ao pid= -o args= |
awk "/[f]oo/ {print \$1}" |
xargs kill -s KILL'
ローカル側では一重引用符を使用し(そこでは変数を展開しない)、リモートシェルコマンドラインでawkコードを二重引用符で囲んでいるため、リモートシェルによって展開されないように$
で$1
をエスケープする必要があります。
awk
はgrep
のスーパーセットです。通常、それらをパイプでつなぐ必要はありません。 ps
に一致させたいものだけを出力するように指示するのが最善です。ここでは、-f
の使用法が示唆するように、psによって表示される引数のリストでfoo
を検索するとします。
リモートユーザーのすべてのプロセス(ここでは、ユーザーfooで、fooとしてsshing)を強制終了する場合は、次のようにします。
ssh foo@<IP Address> 'kill -s KILL -- -1'
これにより、ユーザーが強制終了する権限を持つすべてのプロセスが強制終了されます。通常のユーザーの場合、それは、実際のまたは保存されたユーザーIDが、強制終了プロセスの実際のユーザーIDまたは実効ユーザーIDと同じであるすべてのプロセスです。
または:
ssh foo@<IP Address> 'pkill -KILL -U "$(id -u)"'
(またはpkill -U foo
)。実際のユーザーIDがリモートユーザーの実効ユーザーIDと同じであるすべてのプロセスを強制終了します。
またはあなたがすることができます:
ssh foo@<IP Address> '
trap "" HUP
ps -Ao sid= -o pid= -U "$(id -u)" |
awk "\$1 != $(ps -eo sid= -p "\$\$") {print \$2}" |
xargs kill -s KILL'
(sid
をチェックして、kill
が自分自身、シェル、awk
またはxargs
を殺さないようにし、ユーザーを殺した場合にSIGHUPを無視しますsshd
プロセスにより、そのシグナルが送信されます)
リモートユーザーのログインシェルはBourneに似ていると想定しています。リモートユーザーのログインシェルが、たとえば、異なる構文を持つcshまたはrcファミリーのものである場合、これらのコマンドを適合させる必要があります。
また、信号を番号ではなく名前で参照することをお勧めします。これにより、信号が明確になり、信号番号がシステムごとに変わる可能性があります(ただし、SIGKILLの9は非常に一般的です)。
要するにこれを試してください
ssh user_name@ip_address "pkill -9 foo"
または長いものが欲しいなら
ssh user_name@ip_address "ps aux | grep '[f]oo' | awk '{print \"kill -9 \"\$2}' | bash -v"