간접 확장 내 매개변수 대체

간접 확장 내 매개변수 대체

간접 확장 내에서 매개변수 대체를 구현하고 싶지만 단일 명령으로는 이를 수행할 수 없습니다. "잘못된 대체" 오류가 발생합니다. 이 문제를 해결할 수 있는 현명한 방법이 있는지 알려주세요.

따라서 첫 번째 변수 값을 구문 분석한 다음 이를 간접 확장에서 참조하기 위해 추가 명령을 사용해야 합니다.

첫 번째 변수 값을 구문 분석하기 위한 추가 명령 없이 단일 명령으로 이 작업을 어떻게 수행할 수 있습니까?

$ 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

tempstring 을 얻기 위해 추가 변수를 사용하는 것을 피하고 싶습니다 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}"에 전달합니다. 이는 별도의 인수 로 및 를 사용 하여 호출되는 쉘 코드로 해석됩니다 . 분할+글로브를 방지하려면 외부 및 내부 코드의 따옴표를 참고하세요.evalevalprintf%s\nfinally

bashzsh에서는 '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

관련 정보