Как проверить, установлена ли переменная в Bash?
Как узнать, установлена ли переменная в Bash?
Например, как проверить, дал ли пользователь первый параметр функции?
function a {
# if $1 is set ?
}
Ответы
Ответ 1
(Обычно) Правильный путь
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" ]
будет в порядке.
Ответ 2
Чтобы проверить строковую переменную не -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
Ответ 3
Здесь, как проверить, установлен ли параметр 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", этому назначению присваивается значение, которое также заменяет выражение.
Ответ 4
Хотя большинство методов, изложенных здесь, верны, 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
.
Ответ 5
Существует много способов сделать это, одним из которых является следующее:
if [ -z "$1" ]
Это выполняется, если $1 является null или unset
Ответ 6
Чтобы узнать, не переменна ли переменная, я использую
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
Ответ 7
Я всегда нахожу таблицу 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
VARIABLE
не является пустым (VARIABLE="something"
)
- пустое средство
VARIABLE
пусто /null (VARIABLE=""
)
- unset означает
VARIABLE
не существует (unset VARIABLE
)
Значения:
-
$VARIABLE
означает, что результатом является исходное значение переменной.
-
"default"
означает, что результатом была строка замены.
-
""
означает, что результат равен null (пустая строка).
-
exit 127
означает, что script прекращает выполнение с кодом выхода 127.
-
$(VARIABLE="default")
означает, что результатом является исходное значение переменной, а предоставленная строка замены назначается переменной для будущего использования.
Ответ 8
В современной версии 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
Ответ 9
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
Ответ 10
Вы хотите выйти, если он отключен
Это сработало для меня. Я хотел, чтобы мой 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
Только проверка, без выхода - Empty и Unset - INVALID
Попробуйте этот параметр, если вы просто хотите проверить, установлено ли 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"
Проверить только, нет выхода - только пустой - 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
Ответ 11
Чтобы проверить, установлена ли переменная с непустым значением, используйте [ -n "$x" ]
, как уже указывали другие.
В большинстве случаев рекомендуется обрабатывать переменную с пустым значением так же, как и переменная, которая не установлена. Но вы можете различить два, если вам нужно: [ -n "${x+set}" ]
("${x+set}"
расширяется до set
, если x
установлено и пустая строка, если x
не установлена).
Чтобы проверить, был ли передан параметр, test $#
, который представляет собой число параметров, переданных функции (или в script, если не в функции) (см. Ответ Павла).
Ответ 12
Прочтите раздел "Расширение параметров" на странице руководства 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
в этом примере, просто выйдите, если он не установлен)
Ответ 13
В bash вы можете использовать -v
внутри встроенного [[ ]]
:
#! /bin/bash -u
if [[ ! -v SOMEVAR ]]; then
SOMEVAR='hello'
fi
echo $SOMEVAR
Ответ 14
Для тех, кто хочет проверить, не сброшен или нет, когда в скрипте с 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
не устанавливается без сбоев.
Ответ 15
Заметка
Я даю сильно сфокусированный на 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
, чтобы его никогда не видели, и без изменения кода состояния. Таким образом, функция возвращает только код состояния.
Почему другие методы (иногда) терпят неудачу в Bash
-
[ -n "$var" ]
: проверяется, не является ли ${var[0]}
непустым. (В Bash $var
- это то же самое, что и ${var[0]}
.) -
[ -n "${var+x}" ]
: проверяется только то, установлено ли ${var[0]}
. -
[ "${#var[@]}" != 0 ]
: проверяется только, установлен ли хотя бы один индекс $var
.
Когда этот метод не работает в Bash
Это работает только для именованных переменных (включая $_
), но не определенных специальных переменных ($!
[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}" ]
работает.
Код сравнения для разных методов в Bash
Эта функция сбрасывает переменную 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.
Ответ 16
Использование [[ -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
не затрагивая его код возврата.
Ответ 17
Вы можете сделать:
function a {
if [ ! -z "$1" ]; then
echo '$1 is set'
fi
}
Ответ 18
Ответы выше не работают, если включена опция 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" Режим
Ответ 19
В оболочке вы можете использовать оператор -z
, который является True, если длина строки равна нулю.
Простой однострочный набор для установки по умолчанию MY_VAR
, если он не установлен, в противном случае вы можете отобразить сообщение:
[[ -z "$MY_VAR" ]] && MY_VAR="default"
[[ -z "$MY_VAR" ]] && MY_VAR="default" || echo "Variable already set."
Ответ 20
Мой предпочтительный способ:
$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" ).
Ответ 21
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
Ответ 22
Я всегда использую этот метод, основываясь на том, что его легко понять кто-либо, кто видит код в первый раз:
if [ "$variable" = "" ]
then
echo "Variable X is empty"
fi
И, если вы хотите проверить, не пусто ли,
if [ ! "$variable" = "" ]
then
echo "Variable X is not empty"
fi
Что это.
Ответ 23
Я нашел (намного) лучший код, чтобы сделать это, если вы хотите проверить что-либо в [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
Ответ 24
[[ $foo ]]
или
(( ${#foo} ))
или
let ${#foo}
или
declare -p foo
Ответ 25
Это то, что я использую каждый день:
#
# 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
Ответ 26
if [[ ${!xx[@]} ]] ; then echo xx is defined; fi
Ответ 27
Мне нравятся вспомогательные функции, чтобы скрыть грубые детали 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
Ответ 28
После просмотра всех ответов это также работает:
if [[ -z $SOME_VAR ]]; then read -p "Enter a value for SOME_VAR: " SOME_VAR; fi
echo "SOME_VAR=$SOME_VAR"
Ответ 29
Если вы хотите проверить, что переменная связана или несвязана, это хорошо работает, даже после того, как вы включили опцию nounset:
set -o noun set
if printenv variableName >/dev/null; then
# variable is bound to a value
else
# variable is unbound
fi
Ответ 30
Функции для проверки, объявлена ли переменная /unset
включая пустой $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;}
}
- При первом тестировании, если переменная (un) установлена, вызов declare можно избежать, если это не необходимо.
- Если, однако,
$1
содержит имя пустого $array=()
, вызов объявления будет гарантировать, что мы получим правильный результат
- До сих пор не передавалось много данных в /dev/null, поскольку declare вызывается только в том случае, если переменная не установлена или пустой массив.
Эти функции будут проверяться, как показано в следующих условиях:
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 ответ, поистине случайный. В противном случае, я бы, конечно, придумал это!