ssh
の- ControlMaster 機能を使用して、接続を共有して速度を上げたいと思います。さまざまなホストへの多数の接続を開始/再開/停止できるように、スクリプトを作成しようとしています。
これらの接続のいずれかが使用されているかどうかを確認するにはどうすればよいですか? sshセッションが開いているときにそれらを強制終了すると、閉じられます
私の再起動スクリプトは理想的には(疑似スクリプト)のようになります-停止スクリプトは下部にsshコマンドがなくても同等です:
for Host in $Host_LIST
do
MASTER_PID=`find_master_pid $Host`
if $MASTER_PID
then
if `find_child_pid`
echo Connection to $Host in use: not terminating
else
kill -SIGHUP $MASTER_PID
fi
ssh -TMNf $Host
あなたは単に使用することができます
ssh -o ControlPath=$socket -O check
開いた$ socketごとに(単一のディレクトリに保存しておくと簡単です)。
これは、チェックが失敗した場合(接続がアクティブでなくなった場合)は255を返し、合格した場合は他の値を返します。ホスト名も指定する必要があるかもしれませんが、$ socketのawkでは何も得られません:)
私の現在のアプローチは、lsof
を使用してUnixソケットを見つけることです。 ControlPath
で指定されたターゲットファイル名がわかっている場合は、次のようにマスタープロセスを検索できます。
function find_master_pid() {
lsof -a -U -u $USER -c ssh | grep $CM_DIR/$RUSER@$Host | sed 's/^ssh *//' | cut -d' ' -f1 | sort -u
}
これにより、PID
が得られます(残念ながら、unixソケットファイルのファイル名をlsof
に直接指定しても機能しません。そうでない場合は、pid
と-f
を出力するように要求できます。したがって、sed
とcut
)
子プロセスの検索はより注意が必要です。マスタープロセスは、標準ファイルに接続された子プロセスごとに新しいソケットを開きます。子プロセスには、単にsocket
とマークされたソケットが含まれています。ただし、lsof
によって返されるiノードは、対応するマスタープロセスソケットより1つ少なくなります。したがって、以下はマスタープロセスに接続されている子プロセスを見つけます(これにはチェックするために$MASTER_PID
が必要です)
function find_child_pid() {
for CHILD_PID in `lsof -a -U -u $USER -c ssh | grep socket | sed 's/^ssh *//' | cut -d' ' -f1 | sort -u`
do
CHECK_PID=0
for NODE in `lsof -a -U -u $USER -p $CHILD_PID -F i | grep ^i | sed 's/i//'`
do
MASTER_NODE=$((NODE+1))
CHECK_PID=`lsof -a -U -u $USER -p $MASTER_PID | grep $MASTER_NODE | wc -l`
[[ $CHECK_PID == 1 ]] && echo $CHILD_PID
done
done
}
SSHControlMaster接続の管理を容易にするユーティリティを作成しました。これはcmc
: TimidRobot/cmc:ControlMaster Controller-SSH ControlMaster接続の管理を容易にします と呼ばれます。