Я думаю , что ответ вы после Подразумевается (если не указано иное) на Винко «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}, и так далее.
Как указывает в своем ответе Гили , если вы запускаете с опцией, то основной ответ выше не с . Это легко исправить:bashset -o nounsetunbound 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).