web-dev-qa-db-ja.com

自身をバックグラウンド化したsshプロセスのPIDを取得する

したがって、私は2つのバックグラウンドsshプロセスを呼び出したかったのです。

ssh -D localhost:8087 -fN aws-gateway-vpc1
ssh -D localhost:8088 -fN aws-gateway-vpc2

これらのゲートウェイには、authorized_keysファイルを設定できるという利点がないため、インタラクティブパスワードの入力を求められる必要があります。そのため、シェルの-fではなく&フラグを使用しています。これは、対話的に認証した後にのみプロセスのバックグラウンドになるためです。

このシナリオでは、$! bash変数を使用して最近[自己]バックグラウンドプロセスのPIDを取得することができないようです。

中断された場合に後で強制終了する正しいPIDを見つけるために、他にどのようなオプションがありますか?

6
dlamblin

$!は、現在のシェルによってバックグラウンド化されていないため、機能しません。実際、sshプロセスは、起動元のシェルの子でもありません。私のArchシステムでは、少なくとも、PID 1initプロセスの子として実行されます。

したがって、PIDを取得するには、psを使用するだけです。

$ ssh -f  localhost sleep 100
$ ps aux | grep '[s]sh.*-f'
terdon   20648  0.0  0.0  43308   680 ?        Ss   12:15   0:00 ssh -f localhost sleep 100

PIDが20648であることがわかります*

または、より簡単には、pgrep -fを使用します。

$ pgrep -f 'ssh.*-f'
20648

そして、それを殺すために(それら):

pkill -f 'ssh.*-f'

*grepコマンドの[s]について疑問がある場合は、 this の質問を参照してください。

4
terdon

Greppingでpidを見つけると、エラーが発生しやすくなります。別のオプションは、SSHのControlPathおよびControlMasterオプションを使用することです。これにより、sshコマンドで制御ソケットをリッスンし、後続のssh呼び出しからのコマンドを待つことができます。

これを試して

ssh -D localhost:8087 -S /tmp/.ssh-aws-gateway-vpc1 -M -fN aws-gateway-vpc1
# (...)
# later, when you want to terminate ssh connection
ssh -S /tmp/.ssh-aws-gateway-vpc1 -O exit aws-gateway-vpc1

exitコマンドを使用すると、PIDを知らなくてもプロセスを強制終了できます。何かのPIDが必要な場合は、checkコマンドを使用して表示できます。

$ ssh -S /tmp/.ssh-aws-gateway-vpc1 -O check aws-gateway-vpc1
Master running (pid=1234)
8
Rafał Krypa