bash
다음 표현식은 이의 없이 평가됩니다.
declare -A SPANISH=( [rojo]=red [verde]=green [azul]=blue )
...하지만 이것은 전혀 마음에 들지 않습니다.
declare -A SPANISH=( $( echo "[rojo]=red [verde]=green [azul]=blue" ) )
bash: SPANISH: $( echo "[rojo]=red [verde]=green [azul]=blue" ): must use subscript when assigning associative array
여러 변형을 시도했지만 결과는 항상 must use subscript when assigning associative array
위 오류의 인스턴스 중 하나 이상입니다.
물론 이 예는 어리석다. 유일한 목적은 문제를 설명하는 것입니다.초기화하다세게 때리다명령 대체를 사용한 연관 배열.
이것이 가능합니까?
구체적으로 위의 어리석은 예를 계속하면 <COMMAND>
그러한 명령은 무엇입니까?
declare -A SPANISH=( $( <COMMAND> ) )
...에서 생성된 것과 동일한 최종 결과를 생성합니다.
declare -A SPANISH=( [rojo]=red [verde]=green [azul]=blue )
이상?
그런데 zsh
이 상황을 처리하는 데 아무런 문제가 없습니다.
$ declare -A SPANISH=( $( echo "rojo red verde green azul blue" ) )
$ echo "${SPANISH[azul]}"
blue
답변1
declare -A "SPANISH=($(echo '[rojo]=red [verde]=green [azul]=blue'))"
또는:
declare -A "SPANISH=$(echo '([rojo]=red [verde]=green [azul]=blue)')"
또는:
declare -A "$(echo 'SPANISH=([rojo]=red [verde]=green [azul]=blue)')"
이와 관련하여,
나를 위해 bash 5.1을 사용합니다. 물론 당신도 할 수 있지만 eval
이것이 본질적으로 여기서 일어나는 일이기 때문에 bash는 궁극적으로 명령의 출력을 코드로 해석합니다.
예를 들어,
cmd() { echo '[x$(reboot)]=y'; }
declare -A "a=($(cmd))"
reboot
다음과 동일하게 실행됩니다 .
eval "
declare -A a=($(cmd))
"
명시적으로 사용하면 eval
명령 주입 취약점에 대한 경로가 존재하는 위치가 더 명확해지며, 향후 혼란스러운 설계가 수정될 경우 미래에도 사용할 수 있는 가능성이 높아집니다.
보다 안전한 접근 방식을 위해 cmd
출력 키와 값을 NUL로 구분하고(bash 변수는 NUL을 포함할 수 없으므로) 루프에 연관 배열을 채울 수 있지만 추가 참고 사항으로 bash의 연관 배열은 빈 키가 있는 요소가 있습니다.
fill_assoc() {
local -n _assoc="$1"
local _key _value
while
IFS= read -rd '' _key &&
IFS= read -rd '' _value
do
_assoc[$_key]=$_value
done
}
typeset -A assoc
fill_assoc assoc < <(printf '%s\0' rojo red verde green azul blue)