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

이것은 나에게 효과적입니다.

관련 정보