Acho que a resposta que você está depois está implícito (se não for indicado) por Vinko 's resposta , embora não esteja escrito de forma simples. Para distinguir se o VAR está definido, mas vazio ou não, você pode usar:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "$VAR" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Você provavelmente pode combinar os dois testes na segunda linha em um com:
if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
No entanto, se você ler a documentação do Autoconf, descobrirá que eles não recomendam combinar termos com ' -a
' e recomendam o uso de testes simples separados, combinados com &&
. Eu não encontrei um sistema em que haja um problema; isso não significa que eles não existiam (mas são provavelmente extremamente raros hoje em dia, mesmo que não fossem tão raros no passado distante).
Você pode encontrar os detalhes dessas e de outras expansões de parâmetros de shell relacionadas , o comando test
ou [
expressões condicionais no manual do Bash.
Recentemente, fui perguntado por e-mail sobre esta resposta com a pergunta:
Você usa dois testes e eu entendo bem o segundo, mas não o primeiro. Mais precisamente, não entendo a necessidade de expansão variável
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
Isso não faria o mesmo?
if [ -z "${VAR}" ]; then echo VAR is not set at all; fi
Pergunta justa - a resposta é 'Não, sua alternativa mais simples não faz a mesma coisa'.
Suponha que eu escreva isso antes do seu teste:
VAR=
Seu teste dirá "VAR não está definido", mas o meu dirá (por implicação, porque não ecoa nada) "VAR está definido, mas seu valor pode estar vazio". Experimente este script:
(
unset VAR
if [ -z "${VAR+xxx}" ]; then echo JL:1 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:1 VAR is not set at all; fi
VAR=
if [ -z "${VAR+xxx}" ]; then echo JL:2 VAR is not set at all; fi
if [ -z "${VAR}" ]; then echo MP:2 VAR is not set at all; fi
)
A saída é:
JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all
No segundo par de testes, a variável está definida, mas está definida como o valor vazio. Essa é a distinção que as notações ${VAR=value}
e ${VAR:=value}
fazem. O mesmo vale para ${VAR-value}
e ${VAR:-value}
, e ${VAR+value}
e ${VAR:+value}
, e assim por diante.
Como Gili aponta em sua resposta , se você executar bash
com a set -o nounset
opção, a resposta básica acima falhará unbound variable
. É facilmente remediado:
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
if [ -z "${VAR-}" ] && [ "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Ou você pode cancelar a set -o nounset
opção com set +u
( set -u
sendo equivalente a set -o nounset
).