3つのノードの一部のファイルを更新しようとしています。各接続を特定のユーザーパスにバインドする。私はこれに慣れていないので、for loop
rootとして接続するために使用した拡張を次に拡張しました。nested for loop
2つの異なる配列があります。。
次のスクリプトもちろん、すべての接続で3つのユーザーパスをすべて試してください。。私はarray
withだけを使って試したips
後、各ユーザーが3つのノードすべてに接続しようとしました。
#!/bin/bash
EXTENSIONS='/home/bi/.local/share/gnome-shell/extensions'
NODE_SRVS=(
'[email protected]'
'[email protected]'
'[email protected]'
)
NODE_USERS=(
'mf'
'lf'
'qf'
)
echo -e "sync my extensions to my nodes \c"; read
for i in ${NODE_SRVS[@]}; do
for u in ${NODE_USERS[@]}; do
rsync -rt --delete --info=progress2,stats2 \
-e ssh -tt \
$EXTENSIONS/ \
$i:/home/$u/.local/share/gnome-shell/extensions/
done
done
配列配列を制限する方法はありますか?最初のアレイ接続は、最初のアレイのユーザー名に固有のものです。、など?
そうでなければ何が正しいか各接続をそのユーザーパスにのみ一致させるループ構成はありますか?
ベストアンサー1
うん、繰り返して索引彼らではなく配列のもの価値。しかし、両方の配列はインデックスを共有するので、イテレータ変数は1つだけ必要です($i
下)。
bash
配列は0から始まり、"${#arrayname[@]}"
-を使用して要素数を取得できるため、0からそれより小さい1まで繰り返す必要があります。 3つの要素を含む配列はインデックス0、1、2を持ちます。配列の作成時にインデックスに間隔がないとします。 「間隔」とは、数値インデックスが「欠落している」という意味です(配列に挿入されていないか、挿入後に一定時間が経過すると削除されます)。たとえば、配列にはインデックス1、3、5があります。 2と4がありません。
例えば
i=0
while [ "$i" -lt "${#NODE_SRVS[@]}" ] ; do
# setting $h and $u isn't strictly necessary but makes the code
# easier to read, at little performance cost.
h="${NODE_SRVS[$i]}"
u="${NODE_USERS[$i]}"
rsync -rt --delete --info=progress2,stats2 \
-e ssh -tt \
"$EXTENSIONS/" \
"$h:/home/$u/.local/share/gnome-shell/extensions/
let i+=1
done
すべてのインデックスリストを取得するためにも使用できます"${!arrayname[@]}"
。スペースを無視し、存在するインデックスのみをリストします。以下を使用して繰り返すことができますfor
。
for i in "${!NODE_SRVS[@]}" ; do
h=....
u=...
rsync ...
done
これはインデックス配列には便利ですが(間隔がある可能性があるため)、関連配列には特に便利です。これは次の選択肢につながります。たとえば、ユーザー名は次の連想配列(「ハッシュ」とも呼ばれます)を使用します。キー(インデックス)とホスト名/ IPアドレスは値です(このような単純な場合は、IPアドレスをキーとして、ユーザー名を値として使用することもできます)。
declare -A NODES
NODES=([mf]=192.168.122.60)
NODES+=([lf]=192.168.122.92)
NODES+=([qf]=192.168.122.93)
EXTENSIONS="something"
for u in "${!NODES[@]}"; do
rsync -rt --delete --info=progress2,stats2 \
-e ssh -tt \
"$EXTENSIONS/" \
"$u@${NODES[$u]}:/home/$u/.local/share/gnome-shell/extensions/"
done
echo
先頭に行がある出力の例rsync
:
rsync -rt --delete --info=progress2,stats2 -e ssh -tt something/ [email protected]:/home/qf/.local/share/gnome-shell/extensions/
rsync -rt --delete --info=progress2,stats2 -e ssh -tt something/ [email protected]:/home/lf/.local/share/gnome-shell/extensions/
rsync -rt --delete --info=progress2,stats2 -e ssh -tt something/ [email protected]:/home/mf/.local/share/gnome-shell/extensions/
しかし、Bashの連想配列は本質的に順序がない。つまり、事実上、ランダムな順序でキーを繰り返すという意味です。時にはこれが重要な場合もありますが、そうでない場合もあります。重要でない場合は、連想配列を使用するのが便利です。本当に重要な場合は、上記の最初の例のように2つのインデックス配列を使用してください。
ハッシュの利便性が欲しいが、生成された順序で配列を処理する必要がありますが、インデックス配列を使用し、ハッシュのキーを配列の値にする必要がある場合は、ハッシュを使用します。インデックス配列を繰り返して、挿入順にハッシュのキー名を取得します。例えば
...
ORDER=(mf lf qf)
for u in "${ORDER[@]}"; do
rsync -rt --delete --info=progress2,stats2 \
-e ssh -tt \
"$EXTENSIONS/" \
"$u@${NODES[$u]}:/home/$u/.local/share/gnome-shell/extensions/"
done