2012-11-02 2 views
1

내가에 와서 가장 가까운 솔루션입니다 :배열 키가 있는지 테스트하는 방법은 무엇입니까?

declare -A foobar=([foo]=bar [bar]=foo) 
(set -u; true ${foobar[foo]}) 2>/dev/null 

가 이상적으로 배열 키가 정의되어있는 경우 테스트 test -v를 사용하고 싶습니다. 그러나 test -v foobar[bar]은 항상 1을 반환합니다. 또한 글로벌 set +u을 원하지 않고 정의되지 않은 변수에 액세스 할 위험이 있습니다.

답변

0

"4.2.39 (1) -release"나는 볼 수 없습니다 test -v 명령을 사용하여 배열 키의 존재 여부를 테스트하는 방법. test -v foobar[foo]은 항상 실패합니다. 나에게 최상의 옵션은 ${foobar[foo]-bar} 매개 변수 대체로 테스트해야하는 것처럼 보입니다. 모든 답변에 감사의

#!/bin/bash 

shopt -os nounset 

declare -ri colors=1 
if (("$colors")); then 
    declare -r bold="\e[1m" 
    declare -r red="\e[41m" 
    declare -r green="\e[42m" 
    declare -r end="\e[0;m" 
else 
    declare -r bold= 
    declare -r red= 
    declare -r green= 
    declare -r end= 
fi 
declare -ri a="${1:-0}" 
case "$a" in 
    1) 
    echo -e "$a. Accessing ${bold}\"\$foobar\"${end} when unset should result in an error." 
    echo "$foobar" 
    ;; 
    2) 
    echo -e "$a. Accessing ${bold}\"\${foobar-bar}\"${end} when unset should result in the \"bar\" default value." 
    echo "${foobar-bar}" 
    ;; 
    3) 
    echo -e "$a. Accessing ${bold}\"\${foobar:-bar}\"${end} when unset should result in the \"bar\" default value." 
    echo "${foobar:-bar}" 
    ;; 
    4) 
    echo -e "$a. Accessing ${bold}\"\$foobar\"${end} when set to the NULL string should result in it (whitespace)." 
    declare -r foobar= 
    echo "$foobar" 
    ;; 
    5) 
    echo -e "$a. Accesssing ${bold}\"\${foobar-bar}\"${end} when set to the NULL string should result in it (whitespace)." 
    declare -r foobar= 
    echo "${foobar-bar}" 
    ;; 
    6) 
    echo -e "$a. Accesssing ${bold}\"\${foobar:-bar}\"${end} when set to the NULL string should result in the \"bar\" default value." 
    declare -r foobar= 
    echo "${foobar:-bar}" 
    ;; 
    7) 
    echo -e "$a. Accessing ${bold}\"\$foobar\"${end} when set to the \"foo\" string should result in it." 
    declare -r foobar=foo 
    echo "$foobar" 
    ;; 
    8) 
    echo -e "$a. Accessing ${bold}\"\${foobar-bar}\"${end} when set to the \"foo\" string should result in it." 
    declare -r foobar=foo 
    echo "${foobar-bar}" 
    ;; 
    9) 
    echo -e "$a. Accessing ${bold}\"\${foobar:-bar}\"${end} when set to the \"foo\" string should result in it." 
    declare -r foobar=foo 
    echo "${foobar:-bar}" 
    ;; 
    10) 
    echo -e "$a. Accessing ${bold}\"\${foobar[foo]}\"${end} when unset should result in an error." 
    declare -rA foobar=() 
    echo "${foobar[foo]}" 
    ;; 
    11) 
    echo -e "$a. Accessing ${bold}\"\${foobar[foo]-bar}\"${end} when unset should result in the \"bar\" default value." 
    declare -rA foobar=() 
    echo "${foobar[foo]-bar}" 
    ;; 
    12) 
    echo -e "$a. Accessing ${bold}\"\${foobar[foo]:-bar}\"${end} when unset should result in the \"bar\" default value." 
    declare -rA foobar=() 
    echo "${foobar[foo]:-bar}" 
    ;; 
    13) 
    echo -e "$a. Accessing ${bold}\"\${foobar[foo]}\"${end} when set to the NULL string should result in it (whitespace)." 
    declare -rA foobar=([foo]=) 
    echo "${foobar[foo]}" 
    ;; 
    14) 
    echo -e "$a. Accessing ${bold}\"\${foobar[foo]-bar}\"${end} when set to the NULL string should result in it (whitespace)." 
    declare -rA foobar=([foo]=) 
    echo "${foobar[foo]-bar}" 
    ;; 
    15) 
    echo -e "$a. Accessing ${bold}\"\${foobar[foo]:-bar}\"${end} when set to the NULL string should result in the \"bar\" default value." 
    declare -rA foobar=([foo]=) 
    echo "${foobar[foo]:-bar}" 
    ;; 
    16) 
    echo -e "$a. Testing with ${bold}\"test -v foobar\"${end} when unset should fail." 
    test -v foobar 
    ;; 
    17) 
    echo -e "$a. Testing with ${bold}\"test -v foobar\"${end} when set to the NULL string should succeed." 
    declare -r foobar= 
    test -v foobar 
    ;; 
    18) 
    echo -e "$a. Testing with ${bold}\"test -v foobar\"${end} when set to the \"bar\" string should succeed." 
    declare -r foobar= 
    test -v foobar 
    ;; 
    19) 
    echo -e "$a. Testing with ${bold}\"test -v foobar[foo]\"${end} when unset should fail." 
    declare -rA foobar=() 
    test -v foobar[foo] 
    ;; 
    20) 
    echo -e "$a. Testing with ${bold}\"test -v foobar[foo]\"${end} when set to the NULL string should fail." 
    declare -rA foobar=([foo]=) 
    test -v foobar[foo] 
    ;; 
    21) 
    echo -e "$a. Testing with ${bold}\"test -v foobar[foo]\"${end} when set to the \"bar\" string should succeed." 
    declare -rA foobar=([foo]=bar) 
    test -v foobar[foo] 
    ;; 
    0) 
    echo -e "Testing shopt's \"nounset\" shell option with Bash version \"$BASH_VERSION\"." 
    echo 
    declare -i b 
    for ((b=1; b<=21; b+=1)); do 
     "$0" "$b" 
     if (("$?")); then 
     echo -e "${red}Failure.${end}" 
     else 
     echo -e "${green}Success.${end}" 
     fi 
     echo 
    done 
    ;; 
esac 
0
keys=" ${!foobar[*]} " 
wanted=foo 
if [[ $keys == *" $wanted "* ]]; then 
    echo "foobar contains key $wanted" 
else 
    echo "key $wanted not present" 
fi 

키에 공백이 포함되어 있거나 원하는 키가 "bar foo"또는 연속 된 키의 조합 일 경우 분해 될 수 있습니다.

업데이트 : 이 덜 효율적이 될 수 있지만 (공백 현명한)보다 명확한 안전 모두의 : 배쉬 버전으로

for key in "${!foobar[@]}"; do 
    if [[ $key = $wanted ]]; then 
     echo "foobar contains key $wanted" 
     break 
    fi 
done 
+0

첫째 : shopt 내부의 nounset 쉘 옵션을 선택하고 새로운 버전이 출시 될 때마다 강타의 행동 테스트를 다시하기 위해 나는 다음 배쉬 쉘 스크립트를 썼다. 그러나 당신의 접근 방법은 표현력이 부족할뿐만 아니라 두 개의 부비 트랩을 암시하는 것처럼 더 부서지기 쉬운 것입니다. –

관련 문제