쉘 스크립트를 사용하여 변수의 내용을 인쇄할 수 있습니까? (간접 인용)

쉘 스크립트를 사용하여 변수의 내용을 인쇄할 수 있습니까? (간접 인용)

다음 변수를 선언한다고 가정해 보겠습니다.

$ var='$test'
$ test="my string"

내용을 인쇄하면 다음이 표시됩니다.

$ echo $var
$test

$ echo $test
my string

$var콘텐츠의 내용 (예: the content ) 을 인쇄하는 방법을 찾고 싶습니다 $test. 그래서 나는 다음을 시도합니다.

$ echo $(echo $var)
$test

하지만 결과는 $test그렇지 않습니다 "my string". bash를 사용하여 변수의 내용을 인쇄할 수 있습니까?

답변1

$bash의 간접 변수 확장을 사용하여 이를 수행할 수 있습니다( 변수에서 참조를 생략할 수 있는 한 ):

$ var=test
$ test="my string"
$ echo "$var"
test
$ echo "${!var}"
my string

3.5.3 쉘 매개변수 확장

답변2

var포함된 변수 이름이 접두사로 시작하는 경우 다음을 $사용할 수 있습니다 eval.

$ var='$test'
$ test="my string"
$ eval echo $var
my string

여기서 무슨 일이 일어나고 있나요?

  • bash는 $var가치로 확장되고 명령을 $test생성합니다 eval echo $test.
  • evalecho $test표현식을 평가 하고 원하는 결과를 생성합니다.

일반적인 사용은 eval위험할 수 있으므로(저장된 내용에 따라 var) 피하는 것이 가장 좋습니다. 귀하의 경우에는 간접 확장 기능이 더 적합합니다(단, $로그인을 제거해야 함 $test).

답변3

~처럼Jesse_b의 답변, 그러나 변수 간접 참조 대신 이름 참조를 사용합니다( bash4.3+ 필요).

$ declare -n var=test
$ test="my string"
$ echo "$var"
my string

이름 참조 변수는 var참조하는 변수의 이름을 보유합니다. 변수가 역참조되면 $var다른 변수의 값이 반환됩니다.

bash이름 참조를 재귀적으로 해결합니다.

$ declare -n var1=var2
$ declare -n var2=test
$ test="hello world"
$ echo "$var1"
hello world

완전성을 위해, 연관 배열( bash4.0 이상)을 사용하는 것도 요구 사항에 따라 이 문제를 해결하는 방법입니다.

$ declare -A strings
$ strings[test]="my string"
$ var=test
$ echo "${strings[$var]}"
my string

이는 동적으로 결정될 수 있는 키나 이름을 통해 여러 값에 액세스하는 보다 유연한 방법을 제공합니다. 특정 카테고리의 모든 값을 단일 배열로 수집하고 싶지만 여전히 일부 키(예: ID별 이름, 대상별 경로 이름 등)로 해당 값에 액세스할 수 있는 경우 이는 더 나은 옵션일 수 있습니다. 스크립트의 변수 네임스페이스를 오염시키지 않습니다.

답변4

그리고 zsh:

$ var='$test'
$ test='*'
$ printf '%s\n' ${(e)var}
*

Bourne과 같은 쉘을 사용하십시오.

$ eval 'printf "%s\n" "'"$var"'"'
*

zsh이러한 셸에서는 분할+glob( 예외)을 방지하기 위해 변수 확장을 인용해야 하며 echo임의의 데이터와 함께 사용할 수 없다는 점을 기억하세요.

둘 다 셸 코드 평가 기능이 (e)있으므로 콘텐츠를 제어할 수 있는 eval것이 중요합니다 . 그렇지 않으면 임의의 명령 주입 취약점이 될 수 있습니다( 방법과 동일).$var${!var}

관련 정보