![간접 확장 내 매개변수 대체](https://linux55.com/image/211163/%EA%B0%84%EC%A0%91%20%ED%99%95%EC%9E%A5%20%EB%82%B4%20%EB%A7%A4%EA%B0%9C%EB%B3%80%EC%88%98%20%EB%8C%80%EC%B2%B4.png)
간접 확장 내에서 매개변수 대체를 구현하고 싶지만 단일 명령으로는 이를 수행할 수 없습니다. "잘못된 대체" 오류가 발생합니다. 이 문제를 해결할 수 있는 현명한 방법이 있는지 알려주세요.
따라서 첫 번째 변수 값을 구문 분석한 다음 이를 간접 확장에서 참조하기 위해 추가 명령을 사용해야 합니다.
첫 번째 변수 값을 구문 분석하기 위한 추가 명령 없이 단일 명령으로 이 작업을 어떻게 수행할 수 있습니까?
$ export first="hello"
$ export second_hello="finally"
$ echo ${second_${first}}
bash: ${second_${first}}: bad substitution
$ echo ${!second_${first}}
bash: ${!second_${first}}: bad substitution
$ temp=second_${first}
$ echo ${!temp}
finally
temp
string 을 얻기 위해 추가 변수를 사용하는 것을 피하고 싶습니다 finally
.
답변1
bash
중간 변수가 필요합니다 .
first=hello
second_hello=finally
intermediary=second_$first
printf '%s\n' "${!intermediary}"
다음 표준 방법을 사용하면 언제든지 이 작업을 수행할 수 있습니다 eval
.
eval 'printf "%s\n" "${second_'"$first"'}"'
우리는 이것을 차례로 and printf "%s\n" "${second_hello}"
에 전달합니다. 이는 별도의 인수 로 및 를 사용 하여 호출되는 쉘 코드로 해석됩니다 . 분할+글로브를 방지하려면 외부 및 내부 코드의 따옴표를 참고하세요.eval
eval
printf
%s\n
finally
bash
zsh에서는 's 와 동일하게 매개변수 확장 플래그를 적용하여 중간 변수 없이 확장을 적용할 수 있다는 ${!var}
것입니다 .${(P)var}
P
${:-text}
first=hello
second_hello=finally
printf '%s\n' ${(P)${:-second_$first}}
또는 e
매개변수 확장 플래그를 사용하십시오.
printf '%s\n' ${(e):-\$second_$first}
$first
이러한 모든 방법은 변수 이름에 유효한 문자만 포함되도록 보장된 경우 동일하게 안전하고 그렇지 않으면 동일하게 안전하지 않습니다(임의의 명령 실행 취약점 도입). 따라서 값이 외부에 제공되는 경우 값을 삭제해야 할 수도 있습니다 $first
. 스크립트.
여기서 연관 배열 사용을 고려할 수 있습니다.
typeset -A second
second[hello]=finally
first=hello
printf '%s\n' "${second[$first]}"
export
그러나 환경 변수는 단지 문자열/스칼라이기 때문에 연관 배열 변수를 사용할 수 없습니다 . 하지만 이러한 변수를 내보내려는 것 같지는 않습니다. 매뉴얼 페이지를 찾을 위치를 알기 위해 MANPATH
명령을 내보내어 가져오는 것과 마찬가지로 실행하려는 명령에 의해 "가져온" 변수만 내보내고 싶습니다 .man
답변2
중간 변수를 사용하지 않고 이것을 찾았습니다.
[cloudshell-user@ip-10-0-25-104 ~]$ first=hello
[cloudshell-user@ip-10-0-25-104 ~]$ second_hello=finally
[cloudshell-user@ip-10-0-25-104 ~]$ eval echo \$second_$first
finally