web-dev-qa-db-ja.com

SSH経由でサブシェルコマンドを実行する方法は?

パスワードなしのSSHを介して接続されているコンピューターのクラスターがあり、クラスター全体でコマンドを実行するユーティリティを作成しました。それを行う方法は、ファイルに存在するマシンをピックアップし、SSH経由で指定されたコマンドを実行している間にそれらをループすることです。

次に、クラスターに対してkillコマンドを実行します。これを行う方法は、プロセスIDをgrepしてから、次のようにkillコマンドを実行することです。

_kill -9 $(ps -ef | grep service_name | awk '{print $2}')
_

しかし、このコマンドを実行すると、1台のマシンをループしてコマンドを実行し、2台目のマシンをループして、コマンドを実行せずに終了します。したがって、コマンドは最終的に1台のマシンでのみ実行されることになります。

これについて少し読んだところ、SSH経由で実行されるサブシェルコマンドcmd1 $(cmd2)が正しく実行されないことがわかりました。

誰かが私に回避策を提供できますか?.

1
Punit Naik

実際には、単なるサブシェルではないコマンド置換は正常に機能します。強制終了するプロセスはリモートシステム上のプロセスであるため、問題は、リモートシェルによってリモートシステム上で実行されるようにすることです。したがって、引用する必要があります。これは少し不器用ですが、grepがある場合はawkを削除できます。 2つのオプションは次のとおりです。

ssh user@remote "kill -9 \$(ps -ef | awk '/service_name/{print $2}')"
ssh user@remote 'kill -9 $(ps -ef | awk "/service_name/{print \$2}")'

ただし、ほとんどのLinuxおよび一部の(?)他のUnixでのこの問題のより良い解決策は、特定のコマンドを実行しているプロセスを検索してそれらを強制終了するpkillです。

ssh user@remote pkill -9 service_name

プロセスの起動方法によっては、コマンドライン全体を検索する必要がある場合があります。

ssh user@remote pkill -f -9 service_name
8

Grepをawkにパイプしてはいけません!

ps -ef | awk '/service_name/ { print $2}' | xargs kill -9

または

pkill service_name
6
Archemar

試してください:

ps -ef | grep service_name | awk '{print $2}' | xargs kill -9

最初にテストすることをお勧めします。

1
EightBitTony