나는 예가 내가 필요한 것을 가장 잘 설명한다고 생각합니다.
_v1="windows"
_v2_windows="/mnt/d"
_v2_osx="/Volumes/d"
echo $_v2_`echo $_v1`
_v2_windows
에코하고 싶지만 값을 사용하여 _v1
둘 중 무엇을 얻을지 결정합니다.v2
case
문제를 해결하기 위해 선언을 사용하는 것이 가능하다는 것을 알고 있지만 그렇게 하지 않으려고 노력하고 있습니다.
답변1
그리고 zsh
:
${(P)varname}
에 이름이 저장된 변수의 값을 확장합니다$varname
. 따라서 가 포함되어 있으면 와$varname
동일한 것으로 확장됩니다 .var
${(P)varname}
$var
${(e)var}
의 내용을 확장$var
하지만 그 안에서 매개변수 확장, 명령 대체 및 산술 확장도 수행합니다. 따라서 가 포함되어 있으면 와$var
동일한 것으로 확장됩니다 .$othervar
${(e)var}
$othervar
- 가변 확산 연산자를 중첩할 수 있습니다
${(P)${var:-something}}
. ${:-content}
매개변수 확장을 임의의 텍스트로 확장하는 방법입니다(여기content
).
(바라보다수동세부)
그래서 당신은 이것을 할 수 있습니다 :
_v1=windows
_v2_windows=/mnt/d
printf '%s\n' ${(P)${:-_v2_$_v1}}
또는:
printf '%s\n' ${(e)${:-\$_v2_$_v1}}
아니면 다음 두 단계로 수행합니다.
varname=_v2_$_v1
printf '%s\n' ${(P)varname}
또는:
expansions_to_evaluate=\$_v2_$_v1
printf '%s\n' ${(e)expansions_to_evaluate}
또는 표준 POSIX 구문을 사용할 수 있습니다.
eval 'printf "%s\n" "${_v2_'"$_v1"'}"'
값을 $_v1
제어할 수 없는 경우 이는 모두 임의의 명령 주입 취약점에 해당하므로 먼저 값을 삭제해야 합니다.
또한 zsh
연관 배열이 지원되므로(이전부터 지원되어 왔습니다 bash
) 다음을 수행할 수 있습니다.
typeset -A mnt
mnt=(
windows /mnt/d
osx /Volumes/d
)
os=windows
printf '%s\n' $mnt[$os]
이렇게 하면 더 명확해지고 보안 위험이 발생하지 않습니다.
답변2
printf '%s\n' "${(P)$(echo "_v2_$_v1")}"
또는
var=_v2_$_v1
printf '%s\n' "${(P)var}"
두 경우 모두, 매개변수 확장 플래그는 내부 이름을 우리가 얻으려는 값을 가진 실제 변수의 이름으로 (P)
확장하는 데 사용됩니다 .${...}
이것은비슷한셸 ${!...}
의 변수에 간접적으로 사용됩니다 bash
.