Bash配列の間接アクセス

Bash配列の間接アクセス

次の間接的な操作を実行しようとしています。

host_1=(192.168.0.100 user1 pass1)
host_2=(192.168.0.101 user2 pass2)

hostlist=( "host_1" "host_2" )

for item in ${hostlist[@]}; do

current_host_ip=${!item[0]}
current_host_user=${!item[1]}
current_host_pass=${!item[2]}

echo "IP: $current_host_ip User: $current_host_user Pass: $current_host_pass"

done

この間接要求をどのように実行するかを理解しようとしているので、「hostlist」配列からホスト名を抽出し、間接要求を実行してホスト1 IP、ユーザー、およびパスを抽出する必要があります。ただし、これを試した場合は、最初の変数(IPのみ)を取得するか、その中にあるすべての変数(変数名の末尾に[@]を追加する場合)、空の結果、または数値を取得します。大きなバッチで。まず、host_1配列をcurrent_変数にコピーしてから(スクリプトがいくつかの操作を実行した後)、host_2変数を同じ変数current_に渡す方法を理解していません。

私の間違いを指摘してもらえますか?私はこれが問題に対する解決策だと思いますが、採用することはできません。

配列のすべての要素を間接的に返します。

答え1

配列変数への名前参照を使用できます。

for item in "${hostlist[@]}"; do

  declare -n hostvar=$item
  current_host_ip=${hostvar[0]}
  current_host_user=${hostvar[1]}
  current_host_pass=${hostvar[2]}

  echo "IP: $current_host_ip User: $current_host_user Pass: $current_host_pass"
done

ここで、変数はarrayまたはという変数を意味しますhostvar$itemhost_1host_2

変数間接参照と配列値のコピーを使用します。

for item in "${hostlist[@]}"; do

    x=${item}[@]
    y=( "${!x}" )

    current_host_ip=${y[0]}
    current_host_user=${y[1]}
    current_host_pass=${y[2]}

    echo "IP: $current_host_ip User: $current_host_user Pass: $current_host_pass"
done

答え2

通常、シェルで実行するのは難しい作業は、シェルで行うべきではないタスクを実行しようとするためです。次のことをしないでください。

$ cat tst.sh
#!/usr/bin/env bash

hosts[1]='192.168.0.100 user1 pass1'
hosts[2]='192.168.0.101 user2 pass2'

for item in "${hosts[@]}"; do
    read -r -a current_host <<< "$item"
    echo "IP: ${current_host[0]} User: ${current_host[1]} Pass: ${current_host[2]}"
done

$ ./tst.sh
IP: 192.168.0.100 User: user1 Pass: pass1
IP: 192.168.0.101 User: user2 Pass: pass2

それとも似ていますか?

答え3

よくあるように、私はついに私が望むものを作る方法を見つけました。しかし、私はまだこの解決策が非常に醜く、間接要求の代わりにevalを使用していると思います。したがって、誰かがこのソリューションをよりクールで簡潔で短くすることができる場合は、この質問を開いておきます。とにかく、私がしたことは次のとおりです。

for item in ${hostlist[@]}; do
    eval ip=\( \${${item}[0]} \)
    eval user=\( \${${item}[1]} \)
    eval pass=\( \${${item}[2]} \)
    echo "IP: $ip User: $user Pass: $pass"
done

これは私にとって効果的です。

関連情報