test
, ou seja, [
, precisa de espaços em branco em torno dos operadores, basicamente porque senão foo==
seria considerado como contendo um operador, mesmo que seja uma cadeia válida. A construção [[ .. ]]
funciona da mesma forma. (Veja esta questão e BashFAQ 031 para a diferença [
vs [[
.
Portanto, [ ${aa}=="" ]
será sempre verdadeiro, pois [ string ]
é igual a [ -n string ]
, ou seja, testa se a string não está vazia. E aqui a string contém pelo menos ==
.
Em seguida, [ ${aa} == "" ]
será um erro se aa
não estiver definido ou vazio, pois uma variável vazia expandida sem aspas desaparece e [ == foo ]
não é um teste válido. Se aa
tiver um valor não vazio, é falso. ( [[ ${aa} == "" ]]
funcionaria mesmo sem as aspas, pois [[ .. ]]
é especial.)
É claro que [ "${aa}" == "" ]
testaria que aa
não está definido ou está vazio, o mesmo que [ -z "${aa}" ]
.
Para testar se está definido e vazio, poderíamos usar [ "${aa+x}" ] && [ -z "$aa" ]
, ou uma combinação bacana deles, roubada de um resposta de @ Stéphane Chazelas :
if [ "${aa+x$aa}" = "x" ] ; then
echo "aa is empty but set"
fi
(isso funciona, pois se aa
não estiver definido, a expansão +
expandirá para a sequência vazia e, se estiver definida, será expandida para x$aa
, que é apenas x
se aa
estiver vazio. )
$ foo() { [ "${1+x$1}" = "x" ] && echo "set but empty" || echo "unset or non-empty"; }
$ foo; foo ""; foo bar
unset or non-empty
set but empty
unset or non-empty