1. Estes dois testes retornam verdadeiro :
# [ -d ] && echo true || echo false
true
# [ -d $SOME_UNSET_VAR ] && echo true || echo false
true
de acordo com POSIX (como explicado por @Tim).
2. Mas isso retorna falso ( não true como indicado na pergunta)
# [ -d "" ] && echo true || echo false
false
porque test
é chamado com dois argumentos (embora o segundo seja uma string vazia).
3.
É por isso que é uma boa prática usar [[ … ]]
em vez de test
( [ … ]
), que a maioria dos (todos?) Shells atuais fornecem. Esta construção verifica se você fornece argumentos suficientes (caso contrário, lança um erro e aborta)
# [[ -d ]] && echo true || echo false
bash: unexpected argument ']]' to conditional unary operator
bash: syntax error near ']]'
ou simplesmente se comporta como se esperaria:
# [[ -d $SOME_UNSET_VAR ]] && echo true || echo false
false
4.
E, como apontado por @Gilles, ainda mais importante é a duplicação das substituições. Portanto, -d "$SOME_UNSET_VAR"
expande para -d ""
e retorna falso mesmo com test
(igual ao caso 2). Portanto, isso também é compatível com o shell Bourne sh
:
# [ -d "$SOME_UNSET_VAR" ] && echo true || echo false
false
testado com bash 3.00.16 (1) e 4.1.5 (1)