web-dev-qa-db-ja.com

sshControlMaster接続が使用されているかどうかを確認する方法

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
6
David Fraser

あなたは単に使用することができます

ssh -o ControlPath=$socket -O check 

開いた$ socketごとに(単一のディレクトリに保存しておくと簡単です)。

これは、チェックが失敗した場合(接続がアクティブでなくなった場合)は255を返し、合格した場合は他の値を返します。ホスト名も指定する必要があるかもしれませんが、$ socketのawkでは何も得られません:)

6
Renik

私の現在のアプローチは、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を出力するように要求できます。したがって、sedcut

子プロセスの検索はより注意が必要です。マスタープロセスは、標準ファイルに接続された子プロセスごとに新しいソケットを開きます。子プロセスには、単に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
}
0
David Fraser

SSHControlMaster接続の管理を容易にするユーティリティを作成しました。これはcmcTimidRobot/cmc:ControlMaster Controller-SSH ControlMaster接続の管理を容易にします と呼ばれます。

0
TimZehta