다른 변수의 이름으로 쉘 변수의 확장된 값을 사용하는 방법은 무엇입니까?

다른 변수의 이름으로 쉘 변수의 확장된 값을 사용하는 방법은 무엇입니까?

나는 다음과 같은 작업을 수행하기를 매우 열망하고 있습니다.

#!/bin/bash
MARCOMIN=1
MARCOMAX=3
ENZOMIN=1
ENZOMAX=3
GIOVANNIMIN=1
GIOVANNIMAX=3
VALUEMARCO=12
VALUEGIOVANNI=4
VALUEENZO=12

for i in MARCO ENZO GIOVANNI; do
        echo $$iMIN is $i\'s MIN
        echo $$iMAX is $i\'s MAX
        echo $VALUE$i is $i\'s VALUE
done

exit 0

하지만 내가 원하는 대로 매크로가 작성되지 않습니다.

me@myhost:~$ bash test.sh
20341iMIN is MARCO's MIN
20341iMAX is MARCO's MAX
MARCO is MARCO's VALUE
20341iMIN is ENZO's MIN
20341iMAX is ENZO's MAX
ENZO is ENZO's VALUE
20341iMIN is GIOVANNI's MIN
20341iMAX is GIOVANNI's MAX
GIOVANNI is GIOVANNI's VALUE

분명히 이것은 내 테스트 중 하나 일뿐입니다. 이런 식으로 매크로를 작성하기 위해 여러 가지 방법을 시도했지만 고칠 수 없습니다. 여기와 SO에서 비슷한 질문을 많이 찾았지만 내 상황에 맞는 질문은 없습니다.

bash -x test.sh다음과 같이:

+ MARCOMIN=1
+ MARCOMAX=3
+ ENZOMIN=1
+ ENZOMAX=3
+ GIOVANNIMIN=1
+ GIOVANNIMAX=3
+ VALUEMARCO=12
+ VALUEGIOVANNI=4
+ VALUEENZO=12
+ for i in MARCO ENZO GIOVANNI
+ echo 21466iMIN is 'MARCO'\''s' MIN
21466iMIN is MARCO's MIN
+ echo 21466iMAX is 'MARCO'\''s' MAX
21466iMAX is MARCO's MAX
+ echo MARCO is 'MARCO'\''s' VALUE
MARCO is MARCO's VALUE
+ for i in MARCO ENZO GIOVANNI
+ echo 21466iMIN is 'ENZO'\''s' MIN
21466iMIN is ENZO's MIN
+ echo 21466iMAX is 'ENZO'\''s' MAX
21466iMAX is ENZO's MAX
+ echo ENZO is 'ENZO'\''s' VALUE
ENZO is ENZO's VALUE
+ for i in MARCO ENZO GIOVANNI
+ echo 21466iMIN is 'GIOVANNI'\''s' MIN
21466iMIN is GIOVANNI's MIN
+ echo 21466iMAX is 'GIOVANNI'\''s' MAX
21466iMAX is GIOVANNI's MAX
+ echo GIOVANNI is 'GIOVANNI'\''s' VALUE
GIOVANNI is GIOVANNI's VALUE
+ exit 0

답변1

배쉬 지원가변 간접:

#!/bin/bash
MARCOMIN=1
MARCOMAX=3
ENZOMIN=1
ENZOMAX=3
GIOVANNIMIN=1
GIOVANNIMAX=3
VALUEMARCO=12
VALUEGIOVANNI=4
VALUEENZO=12

for i in MARCO ENZO GIOVANNI; do
    for j in MIN MAX VALUE; do
        varname="${i}${j}"
        # For VALUE we need reverse order of i and j
        [[ $j = VALUE ]] && varname="${j}${i}"

        printf "%d is %s's %s\n" "${!varname}" "$i" "$j"
    done
done

exit 0

내부 루프를 사용하여 추가 작업을 수행하고 printf대신 사용했지만 echo핵심 아이디어는 foo다른 변수에 저장된 변수 이름이 주어지면 bar수행하여 값을 얻을 수 있다는 것입니다.$foo${!bar}

더:https://stackoverflow.com/questions/8515411/what-is-indirect-expansion-what-does-var-mean

답변2

다른 변수의 이름으로 변수 확장을 사용하려면 일반적으로 eval내장 쉘 명령을 사용하여 수행됩니다. 이로 인해 종종 왜곡된 이쑤시개 증후군(많은 백슬래시 및 이중 이스케이프)이 발생하며, 이는 원하는 작업을 수행하는 "더 나은" 방법이 있을 수 있음을 시사합니다. eval내장 기능 사용과 관련된 보안 문제 도 있습니다 .

어쨌든 원하는 것을 달성하는 한 가지 방법은 다음과 같습니다.

# ...
    eval echo \$${i}MIN is \$i\\\'s MIN
    eval echo \$${i}MAX is \$i\\\'s MAX
    eval echo \$VALUE${i} is \$i\\\'s VALUE
# ...

관련 정보