Bash -v test não funciona com matrizes associativas em 4.3.46

3

O operador -v unary que foi introduzido na versão 4.2 para testar se uma variável está configurada ou não parece não funcionar no bash 4.3.46 em matrizes associativas.

Eu tenho um código de teste bash que executo em um conjunto de funções bash, e todas elas passam no bash 4.2 (no CentOS 7.1). Eu recentemente inicializei uma distro Lubuntu 16.04.1 e notei que uma boa parte dos meus testes agora falhavam, com o bash 4.3.46. Parece que todas as falhas se devem ao código assim:

function is_var_set {
    local var="${1:?"No var provided to 'is_var_set'!"}"
    [[ -v "$var" ]]
}

declare -A array=(["a"]="element 1")
is_var_set "array"

Isso é uma coisa amplamente conhecida / o suporte foi removido para matrizes associativas?

    
por krb686 07.11.2016 / 01:16

2 respostas

2

O atual manual do bash sobre matrizes diz

An array variable is considered set if a subscript has been assigned a value.

Então, IMHO, você teria que fazer algo diferente para matrizes associativas. Eu não posso dizer se esta é uma mudança recente no comportamento bash.

Outra maneira de definir is_var_set seria usar (ab) o declare builtin , usando o seguinte:

The return status is zero unless ... one of the names is not a valid shell variable name ...

function is_var_set {
  declare -p "${1:?"No var provided to 'is_var_set'! "}" >& /dev/null
}

O texto acima funcionaria para nomes de variáveis de nível superior, mas não para elementos de matriz específicos.

    
por 07.11.2016 / 03:24
2

Você precisa testar uma matriz, não (somente) o elemento 0.

[[ -v array[@] ]] 

Isso falha:

$ declare -A array=(["a"]="element 1")
$ declare -p array
declare -A array=([a]="element 1" )

$ [[ -v array ]] && echo yes            # nothing is printed.

Mas isso funciona:

$ [[ -v array[@] ]] && echo yes
yes

Então mude sua função para:

function is_var_set {
    local avar="${1:?"No var provided to 'is_var_set'!"}[@]"
    [[ -v "$avar" ]]
}

Teste-o com este script:

function is_var_set {
    local avar="${1:?"No var provided to 'is_var_set'!"}[@]"
    [[ -v "$avar" ]] && echo "$1 set: yes" || echo "$1 set: no"
    echo
}

var=wer
echo "array scalar $(declare -p var)"
is_var_set var

var=( foo bar baz )
echo "var indexed array $(declare -p var)"
is_var_set var

unset var
echo "var associative array $(declare -p var)"
is_var_set var

declare -A var=(["a"]="element 1")
echo "var associative array $(declare -p var)"
is_var_set var
    
por 07.11.2016 / 15:32