Как объясняется в этом ответе, «правильный» способ проверить, установлена ли переменная в bash, выглядит следующим образом:

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

Меня интересует, как извлечь это в функцию, которую можно использовать для разных переменных.

Лучшее, что я смог сделать, это:

is_set() {
  local test_start='[ ! -z ${'
  local test_end='+x} ]'
  local tester=$test_start$1$test_end

  eval $tester
}

Кажется, это работает, но есть ли лучший способ, который не прибегает к вызову eval?

3
ivan 27 Май 2017 в 22:59

2 ответа

Лучший ответ

В Bash вы можете использовать [[ -v var ]]. Там нет необходимости для функции или замысловатых схем.

Из справочной страницы:

   -v varname
          True if the shell variable varname is set (has been assigned a value).

Первые 2 последовательности команд печатают ok:

[[ -v PATH ]] && echo ok

var="" ; [[ -v var ]] && echo ok

unset var ; [[ -v var ]] && echo ok
4
codeforester 28 Май 2017 в 01:55

С [[ ... ]] вы можете просто сделать это (нет необходимости в двойных кавычках):

[[ $var ]] && echo "var is set"
[[ $var ]] || echo "var is not set or it holds an empty string"

Если вам действительно нужна функция, тогда мы можем написать однострочные:

is_empty()     { ! [[ $1 ]]; } # check if not set or set to empty string
is_not_empty() {   [[ $1 ]]; } # check if set to a non-empty string

var="apple"; is_not_empty "$var" && echo "var is not empty" # shows "var is not empty"
var=""     ; is_empty "$var"     && echo "var is empty"     # shows "var is empty"
unset var  ; is_empty "$var"     && echo "var is empty"     # shows "var is empty"
var="apple"; is_empty "$var"     || echo "var is not empty" # shows "var is not empty"

Наконец, is_unset и is_set могут быть реализованы для обработки $1 как имени переменной:

is_unset() {   [[ -z "${!1+x}" ]]; }           # use indirection to inspect variable passed through $1 is unset
is_set()   { ! [[ -z "${!1+x}" ]]; }           # check if set, even to an empty string

unset var; is_unset var && echo "var is unset" # shows "var is unset"
var=""   ; is_set var   && echo "var is set"   # shows "var is set"
var="OK" ; is_set var   && echo "var is set"   # shows "var is set"
1
codeforester 28 Май 2017 в 06:08