Я думаю , что ответ вы после Подразумевается (если не указано иное) на Винко «s ответ , хотя это не прописано просто. Чтобы определить, установлен ли VAR, но не указан или нет, вы можете использовать:
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
Вероятно, вы можете объединить два теста во второй строке в один с помощью:
if [ -z "$VAR" -a "${VAR+xxx}" = "xxx" ]; then echo VAR is set but empty; fi
Однако, если вы прочитаете документацию для Autoconf, вы обнаружите, что они не рекомендуют объединять термины с ' -a
' и рекомендуют использовать отдельные простые тесты в сочетании с &&
. Я не сталкивался с системой, где есть проблема; это не значит, что они не существовали (но они, вероятно, чрезвычайно редки в наши дни, даже если они не были такими редкими в далеком прошлом).
Вы можете найти подробности об этих и других связанных расширениях параметров оболочки , командах test
или [
условных выражениях или в руководстве по Bash.
Меня недавно спросили по электронной почте об этом ответе с вопросом:
Вы используете два теста, и я хорошо понимаю второй, но не первый. Точнее я не понимаю необходимости расширения переменной
if [ -z "${VAR+xxx}" ]; then echo VAR is not set at all; fi
Разве это не достигнет того же самого?
if [ -z "${VAR}" ]; then echo VAR is not set at all; fi
Справедливый вопрос - ответ «Нет, ваша простая альтернатива не делает то же самое».
Предположим, я напишу это перед тестом:
VAR=
Ваш тест скажет «VAR вообще не установлен», но мой скажет (косвенно, потому что он ничего не повторяет) «VAR установлен, но его значение может быть пустым». Попробуйте этот скрипт:
(
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
)
Выход:
JL:1 VAR is not set at all
MP:1 VAR is not set at all
MP:2 VAR is not set at all
Во второй паре тестов переменная установлена, но ей присвоено пустое значение. Это различие, которое делают обозначения ${VAR=value}
и ${VAR:=value}
. То же самое для ${VAR-value}
и ${VAR:-value}
, и ${VAR+value}
и ${VAR:+value}
, и так далее.
Как указывает в своем ответе Гили , если вы запускаете с опцией, то основной ответ выше не с . Это легко исправить:bash
set -o nounset
unbound variable
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
Или вы можете отменить set -o nounset
опцию с помощью set +u
( set -u
эквивалентно set -o nounset
).