Как проверить, установлена ​​ли переменная в Bash? - PullRequest
1308 голосов
/ 30 августа 2010

Как узнать, установлена ​​ли переменная в Bash?

Например, как я могу проверить, передал ли пользователь первый параметр функции?

function a {
    # if $1 is set ?
}

Ответы [ 32 ]

1963 голосов
/ 13 декабря 2012

(обычно) правильный путь

if [ -z ${var+x} ]; then echo "var is unset"; else echo "var is set to '$var'"; fi

где ${var+x} - расширение параметра , которое ничего не вычисляет, если var не установлено, и заменяет строку x в противном случае.

Цитаты Отступление

Кавычки могут быть опущены (поэтому мы можем сказать ${var+x} вместо "${var+x}"), потому что этот синтаксис и использование гарантируют, что это будет расширяться только до чего-то, что не требует кавычек (поскольку оно либо расширяется до x (которое содержит ни одно слово не разрывается, поэтому ему не нужны кавычки) или ничего (что приводит к [ -z ], что удобно для того же значения (true), что и [ -z "" ] также)).

Однако, хотя кавычки могут быть безопасно опущены, и это было не сразу очевидно для всех (это даже не было очевидно для первого автора этого объяснения цитат , который также является основным Bash-кодером), иногда было бы лучше написать решение с кавычками как [ -z "${var+x}" ] при очень небольшой возможной стоимости штрафа за скорость O (1). Первый автор также добавил это в качестве комментария рядом с кодом, использующим это решение, предоставив URL-адрес для этого ответа, который теперь также включает в себя объяснение того, почему кавычки можно безопасно опускать.

(часто) Неправильный путь

if [ -z "$var" ]; then echo "var is blank"; else echo "var is set to '$var'"; fi

Это часто неверно, поскольку не различает переменную, которая не установлена, и переменную, для которой задана пустая строка. То есть, если var='', то вышеприведенное решение выведет "var is blank".

Различие между unset и «set to the empty string» является существенным в ситуациях, когда пользователь должен указать расширение или дополнительный список свойств, и если для них не указано их значение, по умолчанию используется непустое значение, тогда как указывается пустая строка должна заставить скрипт использовать пустое расширение или список дополнительных свойств.

Различие не может быть существенным в каждом сценарии, хотя. В этих случаях [ -z "$var" ] будет просто отлично.

774 голосов
/ 30 августа 2010

Чтобы проверить ненулевую / ненулевую строковую переменную, т.е. если она установлена, используйте

if [ -n "$1" ]

Это противоположно -zЯ использую -n больше, чем -z.

Вы бы использовали это как:

if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi
425 голосов
/ 26 мая 2013

Вот как проверить, является ли параметр unset или empty ("Null") или , установленный со значением :

+--------------------+----------------------+-----------------+-----------------+
|                    |       parameter      |     parameter   |    parameter    |
|                    |   Set and Not Null   |   Set But Null  |      Unset      |
+--------------------+----------------------+-----------------+-----------------+
| ${parameter:-word} | substitute parameter | substitute word | substitute word |
| ${parameter-word}  | substitute parameter | substitute null | substitute word |
| ${parameter:=word} | substitute parameter | assign word     | assign word     |
| ${parameter=word}  | substitute parameter | substitute null | assign word     |
| ${parameter:?word} | substitute parameter | error, exit     | error, exit     |
| ${parameter?word}  | substitute parameter | substitute null | error, exit     |
| ${parameter:+word} | substitute word      | substitute null | substitute null |
| ${parameter+word}  | substitute word      | substitute word | substitute null |
+--------------------+----------------------+-----------------+-----------------+

Источник: POSIX: Расширение параметра :

Во всех случаях, показанных с помощью «замены», выражение заменяется показанным значением.Во всех случаях, показанных с помощью «assign», параметру присваивается это значение, которое также заменяет выражение.

196 голосов
/ 09 июля 2013

Хотя большинство методов, указанных здесь, являются правильными, bash 4.2 поддерживает фактический тест на наличие переменной ( man bash ), а не проверяет значение переменной,

[[ -v foo ]]; echo $?
# 1

foo=bar
[[ -v foo ]]; echo $?
# 0

foo=""
[[ -v foo ]]; echo $?
# 0

Примечательно, что этот подход не приведет к ошибке при использовании для проверки неустановленной переменной в режиме set -u / set -o nounset, в отличие от многих других подходов, таких как [ -z.

174 голосов
/ 30 августа 2010

Есть много способов сделать это, одним из них является следующее:

if [ -z "$1" ]

Это успешно, если $ 1 ноль или не установлено

62 голосов
/ 08 мая 2013

Чтобы проверить, не является ли переменная непустой, я использую

if [[ $var ]]; then ...       # `$var' expands to a nonempty string

Противоположные тесты, если переменная либо не установлена, либо пуста:

if [[ ! $var ]]; then ...     # `$var' expands to the empty string (set or not)

Чтобы узнать, установлена ​​ли переменная(пустой или непустой), я использую

if [[ ${var+x} ]]; then ...   # `var' exists (empty or nonempty)
if [[ ${1+x} ]]; then ...     # Parameter 1 exists (empty or nonempty)

Противоположные тесты, если переменная не установлена:

if [[ ! ${var+x} ]]; then ... # `var' is not set at all
if [[ ! ${1+x} ]]; then ...   # We were called with no arguments
57 голосов
/ 17 июня 2017

Я всегда нахожу таблицу POSIX в другом ответе медленно, чтобы грокать, поэтому вот мое мнение:

   +----------------------+------------+-----------------------+-----------------------+
   |   if VARIABLE is:    |    set     |         empty         |        unset          |
   +----------------------+------------+-----------------------+-----------------------+
 - |  ${VARIABLE-default} | $VARIABLE  |          ""           |       "default"       |
 = |  ${VARIABLE=default} | $VARIABLE  |          ""           | $(VARIABLE="default") |
 ? |  ${VARIABLE?default} | $VARIABLE  |          ""           |       exit 127        |
 + |  ${VARIABLE+default} | "default"  |       "default"       |          ""           |
   +----------------------+------------+-----------------------+-----------------------+
:- | ${VARIABLE:-default} | $VARIABLE  |       "default"       |       "default"       |
:= | ${VARIABLE:=default} | $VARIABLE  | $(VARIABLE="default") | $(VARIABLE="default") |
:? | ${VARIABLE:?default} | $VARIABLE  |       exit 127        |       exit 127        |
:+ | ${VARIABLE:+default} | "default"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+

Обратите внимание, что каждая группа (с и без предшествующего двоеточия)имеет одинаковые значения set и unset , поэтому отличается только то, как обрабатываются пустых случаев.

С предыдущим двоеточиемслучаи empty и unset идентичны, поэтому я бы использовал их, где это возможно (т. е. используйте :=, а не просто =, поскольку пустой регистр несовместим).

Заголовки:

  • set означает VARIABLE не пусто (VARIABLE="something")
  • пусто означает VARIABLE пусто / пусто (VARIABLE="")
  • не установлено означает VARIABLE не существует (unset VARIABLE)

Значения:

  • $VARIABLE означает, что результатом является исходное значение переменной.
  • "default" означает, что результатом была предоставленная замещающая строка.
  • "" означает результат, который яs null (пустая строка).
  • exit 127 означает, что скрипт прекращает выполнение с кодом завершения 127.
  • $(VARIABLE="default") означает, что результатом является исходное значение переменной и предоставленная строка замены назначена переменной для будущего использования.
31 голосов
/ 26 августа 2013

В современной версии Bash (4.2 или более поздней версии, я думаю, я точно не знаю) я бы попробовал это:

20 голосов
/ 30 августа 2010
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi

Хотя для аргументов обычно лучше всего проверить $ #, что, по моему мнению, является числом аргументов.

16 голосов
/ 09 декабря 2016

Вы хотите выйти, если он не установлен

Это сработало для меня.Я хотел, чтобы мой скрипт завершал работу с сообщением об ошибке, если параметр не был установлен.

#!/usr/bin/env bash

set -o errexit

# Get the value and empty validation check all in one
VER="${1:?You must pass a version of the format 0.0.0 as the only argument}"

Возвращается с ошибкой при запуске

peek@peek:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument

Только проверка, нет выхода -Пусто и Неустановлено - НЕВЕРНО

Попробуйте этот вариант, если вы просто хотите проверить, установлено ли значение = ВАЛИД или не установлено / пусто = НЕВЕРНО.

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID
if [ "${TUNSET:-}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

Или даже короткие тесты ;-)

[ "${TSET:-}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY:-}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET:-}" ] && echo "VALID" || echo "INVALID"

Только проверка, нет выхода - только пусто НЕВЕРНО

И это ответ на вопрос.Используйте это, если вы просто хотите проверить, установлено ли значение set / empty = VALID или unset = INVALID.

ПРИМЕЧАНИЕ. «1» в «..- 1}» незначительно, это может быть что угодно (например,x)

TSET="good val"
TEMPTY=""
unset TUNSET

if [ "${TSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TEMPTY+1}" ]; then echo "VALID"; else echo "INVALID";fi
# VALID
if [ "${TUNSET+1}" ]; then echo "VALID"; else echo "INVALID";fi
# INVALID

Короткие тесты

[ "${TSET+1}"   ] && echo "VALID" || echo "INVALID"
[ "${TEMPTY+1}" ] && echo "VALID" || echo "INVALID"
[ "${TUNSET+1}" ] && echo "VALID" || echo "INVALID"

Я посвящаю этот ответ @ mklement0 (комментарии), который призвал меня ответить на вопрос точно.

Ссылка http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_02

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...