bash se declaração comportamento diferente

3

Eu fiz alguns testes do comportamento da instrução bash if , mas não tenho certeza se entendi corretamente o motivo da saída.

Abaixo está o motivo pelo qual estou propondo a cada saída diferente da instrução if , todas as razões estão corretas? Eu também não consigo descobrir a resposta de um dos comportamentos como indicado abaixo. A versão do bash é 4.1.2.

#!/bin/bash

set -x

# behavior 1
if [ $anything ]; then
        echo 'true 1'
fi
# result is false cause $anything will be translated by bash to an empty string, and in 'test' command, EXPRESSION omitted will be false

# behavior 2
if [ '' ];then
        echo 'true 2'
fi
# result is false cause in 'test' command, EXPRESSION omitted will be false

# behavior 3
if [ 0 ]; then
        echo 'true 3'
fi
# result is true cause 0 is a STRING and that is same with '-n STRING', since the length of string '0' is definitely nonzero, so it is true

# behavior 4
if [ ]; then
        echo 'true 4'
fi
# result is false cause in 'test' command, EXPRESSION omitted will be false

# behavior 1a
if $anything; then
        echo 'true 1a'
fi
# result is true. But I don't understand why since bash will translate $anything to an empty string, shouldn't this will result in syntax error ?

# behavior 2a
if ''; then
        echo 'true 2a'
fi
# syntax error cause 'list' is empty and command can not be found

# behavior 3a
if 0; then
        echo 'true 3a'
fi
# syntax error cause 'list' is 0 and there is no such command as 0

# behavior 4a
if ; then
        echo 'true 4a'
fi
# syntax error cause list is empty


set +x
    
por sylye 29.06.2017 / 10:36

2 respostas

3

result is true. But I don't understand why since bash will translate $anything to an empty string, shouldn't this will result in syntax error ?

Fechar, mas sem biscoito. Existe uma expressão: $anything . if ; then é um erro porque o bash falha em analisar o erro (portanto: sintaxe ). Ele espera uma lista de comandos e recebe um ; . A análise acontece bem antes que a expansão de variável aconteça, portanto, if $anything; then analisa bem. O que acontece depois? $anything é expandido e divisão de campo etc. Isso deixa uma lista de comandos vazia, o que é trivialmente verdade. Comparar:

if "$anything"; then echo foo; fi
if $anything; then echo foo; fi

"$anything"; não é uma lista de comandos vazia, tem o comando que acontece com uma string vazia, o mesmo que com if ''; . Mas um "$anything" não expandido se expande para nada.

O mesmo aconteceria se $anything contivesse apenas caracteres de espaço em branco presentes em IFS ou contivesse uma lista de globs% de$IFS separados que não correspondiam a nenhum arquivo e a opção nullglob estivesse ativada. / p>     

por 30.06.2017 / 07:03
0

Os colchetes em instruções como [ "$foo" ] são uma espécie de atalho para o comando test , ou seja, [ "$foo" ] e test "$foo" são equivalentes.

Por outro lado, apenas inserir uma string em branco ou uma string não definida retorna um código de saída true :

unset foo; $foo; echo $?
0

Compare com:

unset foo ; test $foo ; echo $?
1
    
por 30.06.2017 / 07:01