Por que o fn local = $ (…) mascara o $? código de status

3

Duas definições de função, a única diferença é que a primeira combina a palavra-chave local storage com a atribuição, enquanto a segunda separa-as:

function foo {
    local fn=$(mktemp -p /path/does/not/exist 2>/dev/null)
    echo $?
}

function bar {
    local fn
    fn=$(mktemp -p /path/does/not/exist 2>/dev/null)
    echo $?
}

foo
bar

Isto ecoa "0" e depois "1". Eu espero que ele ecoe "1" e depois "1". Parece que o valor de $? é o resultado da atribuição para local, em vez do resultado da substituição de comando.

Por que o bash 4.2.46 (1) -release se comporta dessa maneira?

    
por bishop 07.02.2017 / 20:16

1 resposta

2

Eu achei que esse comportamento foi documentado explicitamente, porque é pegadinha (especialmente ao executar scripts bash com -o errexit !), mas não parece. Minha cópia do manual diz o seguinte (sobre global , que se comporta da mesma forma que local quando dentro de uma função):

The return status is zero unless an invalid option is encountered, an attempt is made to define a function using ‘-f foo=bar’, an attempt is made to assign a value to a readonly variable, an attempt is made to assign a value to an array variable without using the compound assignment syntax [...], one of the names is not a valid shell variable name, an attempt is made to turn off readonly status for a readonly variable, an attempt is made to turn off array status for an array variable, or an attempt is made to display a non-existent function with -f.

Portanto, parece que local não é uma palavra-chave no sentido de que esperaria em outras linguagens de programação: quando uma atribuição-como parâmetro é fornecido para local , que não qualifica o inicialização; em vez disso, o comando interno local cuida de fazendo a atribuição acontecer, e o código de retorno é o de local em si, não do código possivelmente executado no inicializador, e que o código de retorno será diferente de zero na lista de condições listadas acima.

Para talvez responder a pergunta em um sentido mais literal, como bispo mencionado em um comentário, o mantenedor do bash Chet Ramey foi perguntado se ele consideraria fazer local refletir falhas acontecendo durante atribuição, e respondeu, em essência, que atribuição não é local principal missão :

Because that's not what local and its siblings [...] do. These builtins exist to assign and modify variable attributes. As an added feature, they support value assignment at the same time, but the important function is the attribute setting. They don't need to know how the value was computed. [...] Since the function is setting the attribute or value, the exit status should reflect whether or not that succeeded.

    
por 07.02.2017 / 20:39

Tags