私は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
for
3つのループをすべて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
私が望むのは、すべてのサーバーとユーザーを繰り返し、ユーザーと配列、ユーザーserver1
とdanny
配列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
み関連している場合、server1a
server1b
user2
server2a
server2b
server2c
#!/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
動作します。ksh
bash
上記のコードが与えられると、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