キーを使用してサーバーにSSHを接続し、そこから多くのコンテンツを生成する次のスクリプトがあります。
#!/usr/bin/env bash
ssh -i mykey.pem myuser@SERVER_IP << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
(私はこれを実行するために使用しましたsh scriptname.sh
)
別のサーバーで同じことをしたいので、2つの異なるファイル(ip_1
およびip_2
)を使用してSSHを介して2つの異なるサーバー(および)に接続する必要があります。.pem
mykey1.pem
mykey2.pem
これまで、私は次のようにIPを繰り返す方法を知っています。
#!/usr/bin/env bash
ip_list="ip_1 ip_2"
for ip in $ip_list; do
ssh -i mykey.pem myuser@$ip << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done
しかし、今私は正しいpemファイルを得るために繰り返したいと思います。この目標をどのように達成できますか?たぶん別のリストがありますか?誰かが私にエレガントなソリューションを提供できますか?
ip_1
使用すべきmykey1.pem
ip_2
使用すべきmykey2.pem
事前にありがとう
答え1
bashを使用しているので、次のものを使用できます。連想配列:
#!/usr/bin/env bash
declare -A ip_list=(["ip_1"]="mykey1.pem" ["ip_2"]="mykey2.pem")
for ip in "${!ip_list[@]}"; do
ssh -i "${ip_list[$ip]}" myuser@"$ip" << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done
ip_1
通常のインデックス配列とは異なり、連想配列は特定の順序で保存されないため、以前に処理されるという保証はありませんip_2
。
もしあなたなら必要単純な POSIX 互換シェルを使用するには、1 行に 1 つずつ ip ファイルとキーファイルを含むファイルを作成します。
$ cat iplist.txt
ip1 mykey1.pem
ip2 mykey2.pem
次に、次のスクリプトを使用します。
#!/bin/sh
while read -r ip key; do
ssh -i "$key" myuser@"$ip" << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done
そして実行してください:
sh /path/to/script < /path/to/iplist.txt
しかし、その道に行くとスティーブンの方法より良い。
答え2
1つの方法はwhile IFS=, read -r
csv hereドキュメントでループを使用することです。
#! /bin/sh -
while IFS=, read <&3 -r ip key; do
ssh -i "$key" "$ip" << ENDSSH
...
ENDSSH
done 3<< ENDCSV
10.0.0.1,p1.pem
10.0.0.2,p2.pem
ENDCSV
その後、ユーザーにbashをインストールするように要求する必要さえありません。移植性が問題にならない場合は、複数のzsh
変数のループをサポートする代替手段を使用できます。
#! /usr/bin/env zsh
for ip key (
10.0.0.1 p1.pem
10.0.0.2 p2.pem
) ssh -i $key $ip << ENDSSH
...
ENDSSH
答え3
set
元のスクリプトは組み込み機能を使用して移植性をさらに向上させ、IPとキーをコロンで区切られた1つの文字列にまとめることができます。後でプレフィックスとサフィックスの削除を使用してそのアイテムを抽出できます。
#!/usr/bin/env bash
# Set positional parameters
# Example ip addresses
set -- 192.168.0.1:mykey1 192.168.1.1:mykey2
# iterating without specifying 'in' assumes positiona parameters
for host; do
ssh -i ${host##*:}.pem myuser@${host%%:*} << 'ENDSSH'
[A LOT OF STUFF]
ENDSSH
done