루프 변수

루프 변수

저는 약 20개의 다른 서버에서 rsync 및 업데이트 파일을 사용하기 위해 bash 스크립트를 작성하고 있습니다.

rsync 부분을 알아 냈습니다. 내가 겪고 있는 문제는 변수 목록을 탐색하는 것입니다.

지금까지 내 스크립트는 다음과 같습니다.

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"

for ((i=1; i<7; i++))
do
    echo [Server IP Address]
done

[Server IP Address]연관된 변수의 값이어야 합니다 . 따라서 i = 1일 때 $SERVER1의 값을 에코해야 합니다.

나는 다음을 포함하여 여러 번의 반복을 시도했습니다.

echo "$SERVER$i"    # printed the value of i
echo "SERVER$i"     # printer "SERVER" plus the value of i ex: SERVER 1 where i = 1
echo $("SERVER$i")  # produced an error SERVER1: command not found where i = 1
echo $$SERVER$i     # printed a four digit number followed by "SERVER" plus the value of i
echo \$$SERVER$i    # printed "$" plus the value of i

대본을 쓴 지 오랜 시간이 지났기 때문에 뭔가 빠졌다는 것을 알고 있습니다. 또한 저는 C#이 할 수 있는 일을 혼합하고 있다고 확신하며 11년 동안 C#을 사용해 왔습니다.

내가 하고 싶은 일이 가능한 일인가? 아니면 값을 배열에 넣고 배열을 반복해야 합니까? 프로덕션 IP 주소와 위치 이름에도 동일한 것이 필요합니다.

이는 원격 서버에서 파일을 동기화하는 데 사용할 코드 블록을 반복할 필요가 없다는 점입니다.

답변1

배열을 사용하세요.

#! /bin/bash
servers=( 192.xxx.xxx.2 192.xxx.xxx.3
          192.xxx.xxx.4 192.xxx.xxx.5
          192.xxx.xxx.6 192.xxx.xxx.7
)

for server in "${servers[@]}" ; do
    echo "$server"
done

답변2

다른 답변에서 지적했듯이 배열은 이를 수행하는 가장 편리한 방법입니다. 그러나 완전성을 기하기 위해 정확히 귀하가 요구하는 것은간접 확장. 다음과 같이 다시 작성하면 이 접근 방식을 사용해도 예제가 작동합니다.

#!/bin/bash
SERVER1="192.xxx.xxx.2"
SERVER2="192.xxx.xxx.3"
SERVER3="192.xxx.xxx.4"
SERVER4="192.xxx.xxx.5"
SERVER5="192.xxx.xxx.6"
SERVER6="192.xxx.xxx.7"

for ((i=1; i<7; i++))
do
    servervar="SERVER$i"
    echo "${!servervar}"
done

IP 주소 목록을 루프에 넣는 것이 괜찮다면 for, 필요한 모든 것을 반복하기 위해 중괄호 확장을 사용하는 것을 고려할 수도 있습니다.

#!/bin/bash

for server in \
192.xxx.xxx.{2..7} \
192.yyy.yyy.{42..50} \
192.zzz.zzz.254
do
    echo "$server"
done

그러나 (중괄호 확장 가능) 목록을 재사용해야 하는 경우 목록을 사용하여 배열을 초기화하는 것이 올바른 접근 방식입니다.

#!/bin/bash

servers=(
192.xxx.xxx.{2..7} 
192.yyy.yyy.{42..50}
192.zzz.zzz.254 )

for server in "${servers[@]}"
do
    echo "$server"
done

답변3

아마도 배열 답변 중 하나를 선택하고 싶지만 이름을 직접 반복할 수도 있다는 점을 지적하고 싶습니다. 넌 할 수있어

for name in "${!SERVER*}"; do
    echo "${!name}"
done

또는 4.3 이상에서는 다음을 사용할 수 있습니다 nameref.

declare -n name
for name in "${!SERVER*}"; do
    echo "$name"
done

모자 팁이르카초< 4.3에 대한 솔루션.

답변4

배열을 사용해야 한다고 말하는 사람은 모두 옳습니다. 그러나 학문적 연습으로 숫자로 끝나는 별도의 변수(SERVER1, SERVER2 등)를 사용하여 배열을 사용하기로 결정한 경우 다음을 수행합니다.

for ((i=1; i<7; i++))
do
    eval echo \"\$SERVER$i\"
done

관련 정보