1.
Эти два теста возвращают true:
# [ -d ] && echo true || echo false
true
# [ -d $SOME_UNSET_VAR ] && echo true || echo false
true
в соответствии с POSIX (как объяснено @Tim).
2.
Но это возвращает ложь (не верно, как указано в вопросе)
# [ -d "" ] && echo true || echo false
false
потому что test
вызывается с двумя аргументами (хотя второй является пустой строкой).
3.
Вот почему хорошей практикой является использование [[ … ]]
вместо test
([ … ]
), который наиболее (все?) текущие снаряды обеспечивают. Эта конструкция проверяет, достаточно ли вы указали аргументов (в противном случае выдает ошибку и прерывает работу).
# [[ -d ]] && echo true || echo false
bash: unexpected argument `]]' to conditional unary operator
bash: syntax error near `]]'
или просто ведет себя так, как и следовало ожидать:
# [[ -d $SOME_UNSET_VAR ]] && echo true || echo false
false
4.
И, как отмечает @Gilles, еще важнее сделать двойные кавычки. Так что -d "$SOME_UNSET_VAR"
расширяется до -d ""
и возвращает ложь даже с test
(равным случаю 2). Следовательно, это также совместимо с оболочкой Bourne sh
:
# [ -d "$SOME_UNSET_VAR" ] && echo true || echo false
false
протестировано с bash 3.00.16(1) и 4.1.5(1)