간접 참조를 사용하여 변수를 설정할 수 있습니까?

간접 참조를 사용하여 변수를 설정할 수 있습니까?

예를 들어, 다음 스크립트는 규칙 Hello에 따라 인쇄됩니다.${!

A=B
B=Hello
echo ${!A}

하지만 내가 어떻게 할 수 있니?놓다간접 이름을 가진 변수의 값? 기호를 직접 사용하면 !작동하지 않습니다.

A=B
!A=Hello # here is tricky line
echo $B

임시 파일을 사용하는 데 트릭이 있다는 것을 알고 있지만 다음과 같은 것보다는 간접적인 사용에 관심이 있습니다.

A=B
echo "$A=Hello" > 1.tmp
. 1.tmp
echo $B

답변1

typeset내장 함수를 사용하여 이 작업을 수행할 수 있습니다 .

$ A=B
$ typeset $A=42
$ echo $B
42

또는 다음을 사용하십시오 declare.

$ declare $A=1
$ echo $B
1

답변2

따르다변수 값을 얻는 간접적인 방법

이식 가능한 방법은 를 사용하는 것입니다 eval. 값의 특수 문자가 평가되지 않아야 할 때 평가되지 않도록 따옴표를 처리해야 합니다. 가장 간단한 방법은 새 값을 중간 변수에 저장하고 해당 변수의 값을 할당하는 것입니다.

A=B
tmp='stuff with special characters or whatever…'
eval $A=\$tmp

매개변수는 간단한 할당 eval입니다 . B=$tmp공백이나 와일드카드 문자가 포함되어 있더라도 $tmp이러한 문자는 할당에서 확장되지 않으므로 큰따옴표가 필요하지 않습니다.

환경 변수를 생성하려면 를 사용할 수 있습니다 export. bash, ksh 또는 zsh에서는 typeset이를 사용하여 로컬 변수( declarebash의 동의어)를 생성할 수 있습니다. 이번에도 특수 문자가 손상되지 않도록 중간 변수를 사용해야 합니다. zsh를 제외하고는 변수 확장 주위에 큰따옴표가 필요합니다. 이는 할당이 아니라 할당처럼 보이는 인수를 취하는 내장 함수이기 때문입니다.

export $A="$tmp"

답변3

시도해 볼 수 있는 또 다른 방법은 다음과 같습니다.

$ A=B
$ read $A <<< 81
$ echo "$B"
81

그러나 이러한 모든 방법에는 보안 위험(!)이 있습니다. 이 경우 declare왼쪽( 의 값)을 제어해야 합니다. 즉, 적어도 에서는 변수에 입력 파일 등 사용자가 제어하는 ​​입력이 포함되어서는 안 됩니다.typeseteval$Abash$A


쉘이 이 문자열( <<<)을 지원하지 않는 경우 여기에서 문서를 사용할 수도 있습니다.

A=B
read $A << EOF
82
EOF
echo "$B"

답변4

printf또 다른 방법은 이름이 인수로 전달될 수 있는 변수에 출력을 할당하는 with 를 사용하는 것입니다 -v.

A=B
printf -v "$A" '%s' "Hello"
echo ${!A}

관련 정보