スクリプトシェルがIDを取得し、プロセスを強制終了する

スクリプトシェルがIDを取得し、プロセスを強制終了する

コマンドにエラーが見つかりません。

ssh -t root@$machine -x "sshpass -p 'ubuntu' ssh -t root@$address -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/nul -x 'ps -ef | grep "myprocess" | awk {print $2} | xargs kill'"

次のエラーが発生します:

awk: line 2: missing } near end of file

何かアイディアはありますか?

答え1

この種の問題の場合、通常はまずそれを構成要素に分解します。最も内側の式から始めます。この式は、すべての PID を取得myprocessして信号を送ることを目的としているようです。外側に向かって作業を進め、途中で各ステップをテストして、期待どおりの出力が得られることを確認します。

これは、の出力を取得しps、プロセスをgrepし、出力を実行してawk関連するPIDを抽出し、それをxargsに渡すことで実行します。実際に何をしているのかを見てみると、達成しようとしているあなたが直面している特定の問題ではなく、これを行うには、少なくとも2つのより良い方法があります。これにより、偶然にも、直面している問題 (単一の複合コマンド内に複数の引用符のレイヤーがあることに基づく) が完全に回避されます。


1 つは、 を保持しps、その-C-oパラメータを使用して、必要な情報のみを取得することです。これは実際に ps(1) のマニュアル ページに例として記載されています。その場合、次のようになります。

ps -C myprocess -o pid=

これにより、イメージ名を持つプロセスの PID のみが出力されますmyprocess。これを xargs にパイプして、 を次のps ... | xargs killように置き換えるだけで済みます。

ps -C myprocess -o pid= | xargs kill

または、プロセス置換を使用してパイプと xargs を完全に回避することもできます。

kill $( ps -C myprocess -o pid= )

さらに良い代替案killall指定されたイメージ名を持つすべてのプロセスに直接シグナルを送るために使用します。

killall -e myprocess

ここでは、-eプロセス イメージ名が完全に一致する必要がある「正確な」モードを指定します。この場合、全体をps ... | xargs kill上記のものに置き換えます。


-o UserKnownHostsFile=/dev/nul

ああ、慣例的な名前は /dev/null であり、/dev/nul ではありません。NULこれは 1970 年代半ばの CP/M 主義で、Microsoft によって現在のバージョンの Windows に引き継がれています。この特定のケースでは、厳密さの度合いに応じて、効果は同じになる場合とならない場合がありますssh

関連情報