다음 변수를 선언한다고 가정해 보겠습니다.
$ 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
답변2
var
포함된 변수 이름이 접두사로 시작하는 경우 다음을 $
사용할 수 있습니다 eval
.
$ var='$test'
$ test="my string"
$ eval echo $var
my string
여기서 무슨 일이 일어나고 있나요?
- bash는
$var
가치로 확장되고 명령을$test
생성합니다eval echo $test
. eval
echo $test
표현식을 평가 하고 원하는 결과를 생성합니다.
일반적인 사용은 eval
위험할 수 있으므로(저장된 내용에 따라 var
) 피하는 것이 가장 좋습니다. 귀하의 경우에는 간접 확장 기능이 더 적합합니다(단, $
로그인을 제거해야 함 $test
).
답변3
~처럼Jesse_b의 답변, 그러나 변수 간접 참조 대신 이름 참조를 사용합니다( bash
4.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
완전성을 위해, 연관 배열( bash
4.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}