さまざまなユーザーのための複数のSSHセッション

さまざまなユーザーのための複数のSSHセッション

私は3人の異なるユーザーを使用して複数のサーバーに接続するスクリプトを作成しています。

#!/bin/ksh

server1=("abc1" "abc2")
server2=("abc3" "abc4")
server3=("abc5" "abc6")

for i in "${server1[@]}"
do ssh sam@$i "some command"
done

for i in "${server2[@]}"
do ssh danny@$i "some command"
done

for i in "${server3[@]}"
do ssh robert@$i "some command"
done

for3つのループをすべて1つにまとめる方法はありますか?実際、私は複数の接続のためにSSHを書きたいと思います。

すべてのサーバーを1つの配列に配置し、ユーザーを別の配列に配置してみました。

servers=("abc1" "abc2" "abc3" "abc4" "abc5" "abc6")

users=("sam" "Danny" "Robert")

for i in ${servers[@]}
do
 ssh ${users[@]}@$i "some command"
done

ただし、これによりスクリプトはすべてのユーザーをすべてのサーバーに配置し、最終的にサービスアカウントをロックします。

Sam私が望むのは、すべてのサーバーとユーザーを繰り返し、ユーザーと配列、ユーザーserver1danny配列server2、ユーザーrobertと配列のみを一致させるスクリプトですserver3。きれいでより良い方法で正しいユーザーを正しいサーバーに接続するより良い方法はありますか?

答え1

Bashを仮定すると、タグが示すように(shebangで言うkshではない)、次のものを使用できます。名前参照指定された整数識別子に対応する配列変数を使用します。

users=(. userxyz user123 user221)
for n in 1 2 3
do
    declare -n server=server$n
    for i in "${server[@]}"
    do ssh "${users[$n]}@$i" "some command"
    done
done

適切なを使用すると、echo元のスクリプトと同じ出力を取得できます。

ssh userxyz@abc1 some command
ssh userxyz@abc2 some command
ssh user123@abc3 some command
ssh user123@abc4 some command
ssh user221@abc5 some command
ssh user221@abc6 some command

Korn シェルに適応するには、次のものが必要です。nameref組み込みコマンドの使用変えるdeclare -n


より簡単なアプローチでは、ユーザー名/ホスト名を一緒に検討できます。

servers=("userxyz@abc1" "userxyz@abc2"
         "user123@abc3" "user123@abc4"
         "user221@abc5" "user221@abc6")

for i in "${servers[@]}"
do ssh "$i" "some command"
done

答え2

および等とのuser1み関連している場合、server1aserver1buser2server2aserver2bserver2c

#!/bin/sh

set -- \
    user1 server1a server1b -- \
    user2 server2a server2b server2c -- \
    user3 server3a --

while [ "$#" -ne 0 ]; do
    user=$1; shift

    until [ "$1" = -- ]; do
        ssh "$user@$1" 'some command'
        shift
    done

    # Shift off that "--" delimiter
    shift
done

これは、場所パラメータを使用して、ユーザー名とそのサーバーのリストを保存します。これは単一の文字列リストなので、リスト内のユーザー名とサーバー名を含む部分を区別することで、--新しいユーザー名が必要な場合やリストの最後に到達したタイミングを簡単に確認できます。

外部ループはリストの一部を繰り返し、ユーザー名を変数に割り当てますが、user内部ループはサーバー名を繰り返し、ssh文字列が見つかるまで呼び出します。--

スクリプトはのために書かれているので、でも/bin/sh動作します。kshbash

上記のコードが与えられると、ssh次のコマンドが実行されます。

ssh user1@server1a 'some command'
ssh user1@server1b 'some command'
ssh user2@server2a 'some command'
ssh user2@server2b 'some command'
ssh user2@server2c 'some command'
ssh user3@server3a 'some command'

初期コマンドを削除すると、set次のようにコマンドラインからスクリプトを呼び出して同じ効果を得ることができます。

$ ./script user1 server1a server1b -- user2 server2a server2b server2c -- user3 server3a --

内部ループで追加のチェック()を実行して、コマンドラインから|| [ "$#" -eq 0 ]最後のチェックを省略できます。--


やりたいことが申請なら乾燥原理コードの 1 つのポイントでのみ呼び出し、そのsshビットを関数として抽出します。このために修正されたコードは次のとおりです。

#!/bin/ksh

server1=("abc1" "abc2")
server2=("abc3" "abc4")
server3=("abc5" "abc6")

process () {
    ssh "$1@$2" 'some command'
}

for server in "${server1[@]}"; do
    process sam "$server"
done

for server in "${server2[@]}"; do
    process danny "$server"
done

for server in "${server3[@]}"; do
    process robert "$server"
done

関連情報