Как узнать, установлена ли переменная в Bash?
Например, как проверить, дал ли пользователь первый параметр функции?
function a {
    # if $1 is set ?
}
Как узнать, установлена ли переменная в Bash?
Например, как проверить, дал ли пользователь первый параметр функции?
function a {
    # if $1 is set ?
}
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" ] будет в порядке.
Чтобы проверить строковую переменную не -n ULL/не -z, т.е. Если она установлена, используйте
if [ -n "$1" ]
 Это противоположность -z. Я использую -n больше, чем -z.
Вы бы использовали это как:
if [ -n "$1" ]; then
  echo "You supplied the first parameter!"
else
  echo "First parameter not supplied."
fi
Здесь, как проверить, установлен ли параметр unset, или пустой ( "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: расширение параметров:
Во всех случаях, показанных с помощью "substitute", выражение заменяется показанным значением. Во всех случаях, показанных с помощью "assign", этому назначению присваивается значение, которое также заменяет выражение.
Хотя большинство методов, изложенных здесь, верны, bash 4.2 поддерживает фактический тест на наличие переменной (man bash), а не тестирует значение переменной.
[[ -v foo ]]; echo $?
# 1
foo=bar
[[ -v foo ]]; echo $?
# 0
foo=""
[[ -v foo ]]; echo $?
# 0
 Примечательно, что этот подход не вызовет ошибки при использовании для проверки set -u переменной в режиме set -u/set -o nounset, в отличие от многих других подходов, таких как использование [ -z.
Существует много способов сделать это, одним из которых является следующее:
if [ -z "$1" ]
Это выполняется, если $1 является null или unset
Чтобы узнать, не переменна ли переменная, я использую
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
Я всегда нахожу таблицу 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"  |          ""           |          ""           |
   +----------------------+------------+-----------------------+-----------------------+
Обратите внимание, что каждая группа (с и без предшествующего двоеточия) имеет одинаковый набор и отменяет случаи, поэтому единственное, что отличается, - это то, как обрабатываются пустые случаи.
В предыдущем двоеточии пустые и неустановленные случаи идентичны, поэтому я бы использовал их там, где это было возможно (т.е. использовать :=, а не только =, потому что пустой случай несовместим).
Заголовки:
VARIABLE не является пустым (VARIABLE="something")VARIABLE пусто /null (VARIABLE="")VARIABLE не существует (unset VARIABLE)Значения:
$VARIABLE означает, что результатом является исходное значение переменной."default" означает, что результатом была строка замены."" означает, что результат равен null (пустая строка).exit 127 означает, что script прекращает выполнение с кодом выхода 127.$(VARIABLE="default") означает, что результатом является исходное значение переменной, а предоставленная строка замены назначается переменной для будущего использования.В современной версии Bash (4.2 или более поздней, я думаю, я точно не знаю), я бы попробовал это:
if [ ! -v SOMEVARIABLE ] #note the lack of a $ sigil
then
    echo "Variable is unset"
elif [ -z "$SOMEVARIABLE" ]
then
    echo "Variable is set to an empty string"
else
    echo "Variable is set to some string"
fi
if [ "$1" != "" ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi
Хотя для аргументов, как правило, лучше всего проверять $#, что является числом аргументов, на мой взгляд.
if [ $# -gt 0 ]; then
  echo \$1 is set
else
  echo \$1 is not set
fi
Это сработало для меня. Я хотел, чтобы мой script вышел с сообщением об ошибке, если параметр не был установлен.
#!/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}"
Это возвращается с ошибкой при запуске
[email protected]:~$ ./setver.sh
./setver.sh: line 13: 1: You must pass a version of the format 0.0.0 as the only argument
Попробуйте этот параметр, если вы просто хотите проверить, установлено ли value = VALID или unset/empty = INVALID.
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"
И это ответ на вопрос. Используйте это, если вы просто хотите проверить, установлено ли значение/пусто = 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
Чтобы проверить, установлена ли переменная с непустым значением, используйте [ -n "$x" ], как уже указывали другие.
В большинстве случаев рекомендуется обрабатывать переменную с пустым значением так же, как и переменная, которая не установлена. Но вы можете различить два, если вам нужно: [ -n "${x+set}" ] ("${x+set}" расширяется до set, если x установлено и пустая строка, если x не установлена).
Чтобы проверить, был ли передан параметр, test $#, который представляет собой число параметров, переданных функции (или в script, если не в функции) (см. Ответ Павла).
Прочтите раздел "Расширение параметров" на странице руководства bash. Расширение параметров не дает общего теста для заданной переменной, но есть несколько вещей, которые вы можете сделать с параметром, если он не установлен.
Например:
function a {
    first_arg=${1-foo}
    # rest of the function
}
установит first_arg равным $1, если он назначен, иначе он использует значение "foo". Если a абсолютно необходимо принять один параметр и не существует хорошего значения по умолчанию, вы можете выйти с сообщением об ошибке, если не задан параметр:
function a {
    : ${1?a must take a single argument}
    # rest of the function
}
(Обратите внимание на использование : как команды null, которая просто расширяет значения его аргументов. Мы не хотим ничего делать с $1 в этом примере, просто выйдите, если он не установлен)
В bash вы можете использовать -v внутри встроенного [[ ]]:
#! /bin/bash -u
if [[ ! -v SOMEVAR ]]; then
    SOMEVAR='hello'
fi
echo $SOMEVAR
 Для тех, кто хочет проверить, не сброшен или нет, когда в скрипте с  set -u:
if [ -z "${var-}" ]; then
   echo "Must provide var environment variable. Exiting...."
   exit 1
fi
 Регулярная [ -z "$var" ] не будет выполнена с var; unbound variable var; unbound variable если set -u но [ -z "${var-}" ] расширяется до пустой строки, если var не устанавливается без сбоев.
 Я даю сильно сфокусированный на Bash ответ из-за тега bash.
Пока вы имеете дело только с именованными переменными в Bash, эта функция всегда должна сообщать вам, установлена ли переменная, даже если это пустой массив.
is-variable-set() {
    declare -p $1 &>dev/null
}
 В Bash (по крайней мере, начиная с declare -p var 3.0), если var является объявленной/установленной переменной, то declare -p var выводит команду declare, которая установит переменную var declare -p var ее текущему типу и значению, и возвращает код состояния 0 (успех). Если var не объявлена, то declare -p var выводит сообщение об ошибке в stderr и возвращает код состояния 1. Используя &>/dev/null, перенаправляет как обычный stdout и stderr в /dev/null, чтобы его никогда не видели, и без изменения кода состояния. Таким образом, функция возвращает только код состояния.
[ -n "$var" ]: проверяется, не является ли${var[0]}непустым. (В Bash$var- это то же самое, что и${var[0]}.)
[ -n "${var+x}" ]: проверяется только то, установлено ли${var[0]}.
[ "${#var[@]}" != 0 ]: проверяется только, установлен ли хотя бы один индекс$var.
 Это работает только для именованных переменных (включая $_), но не определенных специальных переменных ($! [email protected], $#, $$, $*, $? $-, $0, $1, $2 ,... и любых других. Возможно, я забыл) Поскольку ни один из них не является массивом, POSIX-стиль [ -n "${var+x}" ] работает для всех этих специальных переменных. Но остерегайтесь оборачивать его в функцию, так как многие специальные переменные изменяют значения/существование при вызове функций.
 Если в вашем сценарии есть массивы, и вы пытаетесь сделать его совместимым с максимально возможным количеством оболочек, рассмотрите возможность использования typeset -p вместо declare -p. Я читал, что ksh поддерживает только первое, но не смог проверить это. Я знаю, что Bash 3. 0+ и Zsh 5.5.1 каждый поддерживает оба typeset -p и declare -p, отличаясь только тем, что одно является альтернативой другому. Но я не проверял различия между этими двумя ключевыми словами и не проверял другие оболочки.
 Если вам нужен ваш POSIX-совместимый скрипт, то вы не можете использовать массивы. Без массивов [ -n "{$var+x}" ] работает.
 Эта функция сбрасывает переменную var, eval пройденный код, запускает тесты, чтобы определить, является ли var устанавливается eval г кода, и, наконец, показывает результирующие коды состояния для различных тестов.
 Я пропускаю test -v var, [ -v var ] и [[ -v var ]] потому что они дают идентичные результаты стандарту POSIX [ -n "${var+x}" ], в то время как требующий Bash 4. 2+. Я также пропускаю typeset -p потому что он аналогичен declare -p в оболочках, которые я тестировал (Bash 3.0 через 5.0 и Zsh 5.5.1).
is-var-set-after() {
    # Set var by passed expression.
    unset var
    eval "$1"
    # Run the tests, in increasing order of accuracy.
    [ -n "$var" ] # (index 0 of) var is nonempty
    nonempty=$?
    [ -n "${var+x}" ] # (index 0 of) var is set, maybe empty
    plus=$?
    [ "${#var[@]}" != 0 ] # var has at least one index set, maybe empty
    count=$?
    declare -p var &>/dev/null # var has been declared (any type)
    declared=$?
    # Show test results.
    printf '%30s: %2s %2s %2s %2s\n' "$1" $nonempty $plus $count $declared
}
Обратите внимание, что результаты теста могут быть неожиданными из-за того, что Bash рассматривает не числовые индексы -n как "0", если переменная не была объявлена как ассоциативный массив. Кроме того, ассоциативные массивы действительны только в Bash 4. 0+.
# Header.
printf '%30s: %2s %2s %2s %2s\n' "test" '-n' '+x' '#@' '-p'
# First 5 tests: Equivalent to setting 'var=foo' because index 0 of an
# indexed array is also the nonindexed value, and non-numerical
# indices in an array not declared as associative are the same as
# index 0.
is-var-set-after "var=foo"                        #  0  0  0  0
is-var-set-after "var=(foo)"                      #  0  0  0  0
is-var-set-after "var=([0]=foo)"                  #  0  0  0  0
is-var-set-after "var=([x]=foo)"                  #  0  0  0  0
is-var-set-after "var=([y]=bar [x]=foo)"          #  0  0  0  0
# '[ -n "$var" ]' fails when var is empty.
is-var-set-after "var=''"                         #  1  0  0  0
is-var-set-after "var=([0]='')"                   #  1  0  0  0
# Indices other than 0 are not detected by '[ -n "$var" ]' or by
# '[ -n "${var+x}" ]'.
is-var-set-after "var=([1]='')"                   #  1  1  0  0
is-var-set-after "var=([1]=foo)"                  #  1  1  0  0
is-var-set-after "declare -A var; var=([x]=foo)"  #  1  1  0  0
# Empty arrays are only detected by 'declare -p'.
is-var-set-after "var=()"                         #  1  1  1  0
is-var-set-after "declare -a var"                 #  1  1  1  0
is-var-set-after "declare -A var"                 #  1  1  1  0
# If 'var' is unset, then it even fails the 'declare -p var' test.
is-var-set-after "unset var"                      #  1  1  1  1
 Тестовая мнемоника в строке заголовка соответствует [ -n "$var" ], [ -n "${var+x}" ], [ "${#var[@]}" != 0 ] и declare -p var, соответственно.
                         test: -n +x #@ -p
                      var=foo:  0  0  0  0
                    var=(foo):  0  0  0  0
                var=([0]=foo):  0  0  0  0
                var=([x]=foo):  0  0  0  0
        var=([y]=bar [x]=foo):  0  0  0  0
                       var='':  1  0  0  0
                 var=([0]=''):  1  0  0  0
                 var=([1]=''):  1  1  0  0
                var=([1]=foo):  1  1  0  0
declare -A var; var=([x]=foo):  1  1  0  0
                       var=():  1  1  1  0
               declare -a var:  1  1  1  0
               declare -A var:  1  1  1  0
                    unset var:  1  1  1  1
declare -p var &>/dev/null(100%?) надежно для тестирования именованных переменных в Bash, начиная с версии 3.0.
[ -n "${var+x}" ]надежен в ситуациях, соответствующих POSIX, но не может обрабатывать массивы.- Существуют другие тесты для проверки, является ли переменная непустой, и для проверки объявленных переменных в других оболочках. Но эти тесты не подходят ни для скриптов Bash, ни для POSIX.
 Использование [[ -z "$var" ]] - это самый простой способ узнать, установлена ли переменная или нет, но эта опция -z не различает -z переменную и переменную, установленную в пустую строку:
$ set=''
$ [[ -z "$set" ]] && echo "Set" || echo "Unset" 
Unset
$ [[ -z "$unset" ]] && echo "Set" || echo "Unset"
Unset
Лучше всего проверять его по типу переменной: переменная env, параметр или обычная переменная.
Для переменной env:
[[ $(env | grep "varname=" | wc -l) -eq 1 ]] && echo "Set" || echo "Unset"
 Для параметра (например, чтобы проверить наличие параметра $5):
[[ $# -ge 5 ]] && echo "Set" || echo "Unset"
Для обычной переменной (используя вспомогательную функцию, чтобы сделать это элегантным способом):
function declare_var {
   declare -p "$1" &> /dev/null
}
declare_var "var_name" && echo "Set" || echo "Unset"
Заметки:
$#: дает количество позиционных параметров.
declare -p: дает определение переменной, переданной в качестве параметра. Если он существует, возвращает 0, если нет, возвращает 1 и печатает сообщение об ошибке.
&>/dev/null: подавляет вывод командыdeclare -pне затрагивая его код возврата.
Вы можете сделать:
function a {
        if [ ! -z "$1" ]; then
                echo '$1 is set'
        fi
}
Ответы выше не работают, если включена опция Bash set -u. Кроме того, они не являются динамическими, например, как проверяется переменная с именем "dummy"? Попробуйте следующее:
is_var_defined()
{
    if [ $# -ne 1 ]
    then
        echo "Expected exactly one argument: variable name as string, e.g., 'my_var'"
        exit 1
    fi
    # Tricky.  Since Bash option 'set -u' may be enabled, we cannot directly test if a variable
    # is defined with this construct: [ ! -z "$var" ].  Instead, we must use default value
    # substitution with this construct: [ ! -z "${var:-}" ].  Normally, a default value follows the
    # operator ':-', but here we leave it blank for empty (null) string.  Finally, we need to
    # substitute the text from $1 as 'var'.  This is not allowed directly in Bash with this
    # construct: [ ! -z "${$1:-}" ].  We need to use indirection with eval operator.
    # Example: $1="var"
    # Expansion for eval operator: "[ ! -z \${$1:-} ]" -> "[ ! -z \${var:-} ]"
    # Code  execute: [ ! -z ${var:-} ]
    eval "[ ! -z \${$1:-} ]"
    return $?  # Pedantic.
}
Связано: В Bash, как я могу проверить, определена ли переменная в "-u" Режим
В оболочке вы можете использовать оператор -z, который является True, если длина строки равна нулю.
Простой однострочный набор для установки по умолчанию MY_VAR, если он не установлен, в противном случае вы можете отобразить сообщение:
[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."
Мой предпочтительный способ:
$var=10
$if ! ${var+false};then echo "is set";else echo "NOT set";fi
is set
$unset var
$if ! ${var+false};then echo "is set";else echo "NOT set";fi
NOT set
В принципе, если переменная установлена, она становится "отрицанием результирующего false" (что будет установлено true= ").
И, если он не установлен, он станет "отрицанием результирующего true" (поскольку пустой результат оценивается как true) (поэтому он заканчивается как false= "NOT set" ).
if [[ ${1:+isset} ]]
then echo "It was set and not null." >&2
else echo "It was not set or it was null." >&2
fi
if [[ ${1+isset} ]]
then echo "It was set but might be null." >&2
else echo "It was was not set." >&2
fi
Я всегда использую этот метод, основываясь на том, что его легко понять кто-либо, кто видит код в первый раз:
if [ "$variable" = "" ]
    then
    echo "Variable X is empty"
fi
И, если вы хотите проверить, не пусто ли,
if [ ! "$variable" = "" ]
    then
    echo "Variable X is not empty"
fi
Что это.
Я нашел (намного) лучший код, чтобы сделать это, если вы хотите проверить что-либо в [email protected].
if [[ $1 = "" ]] then echo '$1 is blank' else echo '$1 is filled up' fi
Почему все это? Все в [email protected] существует в Bash, но по умолчанию оно пустое, поэтому test -z и test -n не могут вам помочь.
Обновление: Вы можете также подсчитать количество символов в параметрах.
if [ ${#1} = 0 ]
then
  echo '$1 is blank'
else
  echo '$1 is filled up'
fi
		[[ $foo ]]
или
(( ${#foo} ))
или
let ${#foo}
или
declare -p foo
Это то, что я использую каждый день:
#
# Check if a variable is set
#   param1  name of the variable
#
function is_set()
{
    [[ -n "${1}" ]] && test -n "$(eval "echo "\${${1}+x}"")"
}
Это хорошо работает под Linux и Solaris до bash 3.0.
bash-3.00$ myvar="TEST"
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ mavar=""
bash-3.00$ is_set myvar ; echo $?
0
bash-3.00$ unset myvar
bash-3.00$ is_set myvar ; echo $?
1
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi
Мне нравятся вспомогательные функции, чтобы скрыть грубые детали bash. В этом случае это добавляет еще большую (скрытую) грубость:
# The first ! negates the result (can't use -n to achieve this)
# the second ! expands the content of varname (can't do ${$varname})
function IsDeclared_Tricky
{
  local varname="$1"
  ! [ -z ${!varname+x} ]
}
Поскольку у меня сначала были ошибки в этой реализации (вдохновленные ответами Йенса и Лионеля), я придумал другое решение:
# Ask for the properties of the variable - fails if not declared
function IsDeclared()
{
  declare -p $1 &>/dev/null
}
Я считаю, что это более прямолинейно, более баски и легче понять/запомнить. В тестовом примере это эквивалентно:
function main()
{
  declare -i xyz
  local foo
  local bar=
  local baz=''
  IsDeclared_Tricky xyz; echo "IsDeclared_Tricky xyz: $?"
  IsDeclared_Tricky foo; echo "IsDeclared_Tricky foo: $?"
  IsDeclared_Tricky bar; echo "IsDeclared_Tricky bar: $?"
  IsDeclared_Tricky baz; echo "IsDeclared_Tricky baz: $?"
  IsDeclared xyz; echo "IsDeclared xyz: $?"
  IsDeclared foo; echo "IsDeclared foo: $?"
  IsDeclared bar; echo "IsDeclared bar: $?"
  IsDeclared baz; echo "IsDeclared baz: $?"
}
main
В тестовом примере также показано, что local var  NOT объявляет var (если не следовать '='). В течение некоторого времени я думал, что я объявил переменные таким образом, просто чтобы узнать теперь, что я просто выразил свое намерение... Это не-op, я думаю.
IsDeclared_Tricky xyz: 1
IsDeclared_Tricky foo: 1
Панель IsDeclared_Tricky: 0
IsDeclared_Tricky baz: 0
IsDeclared xyz: 1
IsDeclared foo: 1
Панель IsDeclared: 0
IsDeclared baz: 0
БОНУС: usecase
В основном я использую этот тест, чтобы дать (и возвращать) параметры функциям несколько "элегантным" и безопасным способом (почти напоминающим интерфейс...):
#auxiliary functions
function die()
{
  echo "Error: $1"; exit 1
}
function assertVariableDeclared()
{
  IsDeclared "$1" || die "variable not declared: $1"
}
function expectVariables()
{
  while (( $# > 0 )); do
    assertVariableDeclared $1; shift
  done
}
# actual example
function exampleFunction()
{
  expectVariables inputStr outputStr
  outputStr="$inputStr world!"
}
function bonus()
{
  local inputStr='Hello'
  local outputStr= # remove this to trigger error
  exampleFunction
  echo $outputStr
}
bonus
Если вызов со всеми требует объявленных переменных:
Привет мир!
еще:
Ошибка: переменная не объявлена: outputStr
После просмотра всех ответов это также работает:
if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"
Если вы хотите проверить, что переменная связана или несвязана, это хорошо работает, даже после того, как вы включили опцию nounset:
set -o noun set
if printenv variableName >/dev/null; then
    # variable is bound to a value
else
    # variable is unbound
fi
$array=() 
Следующие функции проверяют, существует ли данное имя как переменная
# The first parameter needs to be the name of the variable to be checked.
# (See example below)
var_is_declared() {
    { [[ -n ${!1+anything} ]] || declare -p $1 &>/dev/null;}
}
var_is_unset() {
    { [[ -z ${!1+anything} ]] && ! declare -p $1 &>/dev/null;} 
}
$1 содержит имя пустого $array=(), вызов объявления будет гарантировать, что мы получим правильный результатЭти функции будут проверяться, как показано в следующих условиях:
a; # is not declared a=; # is declared a="foo"; # is declared a=(); # is declared a=(""); # is declared unset a; # is not declared a; # is unset a=; # is not unset a="foo"; # is not unset a=(); # is not unset a=(""); # is not unset unset a; # is unset
.
Подробнее...
и тест script см. мой ответ на вопрос "Как проверить, существует ли переменная в bash?" .
Примечание: Аналогичное использованиеdeclare -p, как это показано также Peregring-lk ответ, поистине случайный. В противном случае, я бы, конечно, придумал это!