it-swarm.com.ru

Сценарий оболочки - выход из сценария, если переменная равна нулю или пуста

Я ожидаю использовать нижеприведенную переменную в моем скрипте bash, но в случае, если она пуста или равна нулю, что будет лучшим способом обработать ее и выйти из скрипта.

tag=$1  

Я вижу ответы с «set -u». Я знаю, что это будет работать, но хорошо ли это для производственной среды?

12
Pinaki Mukherjee

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

tag=${1?Need a value}

Обычно это используется с : no-op в начале скрипта.

: ${1?Need a value}

Соотношение «незаданное или пустое» несколько иное. Не существует аналогичной конструкции для выхода при пустом, но заданном значении, но вы можете легко использовать связанный синтаксис ${var:-default}, который расширяется до $var, если он задан и не пуст, и default в противном случае. Существует также ${var-default}, который создает default, только если переменная не установлена ​​правильно.

Это может быть особенно полезно, когда вы хотите использовать set -u, но вам нужно справиться с возможно неустановленной переменной:

case ${var-} in '') echo "$0: Need a value in var" >&2; exit 1;; esac

Я несколько предпочитаю case, а не if [ "${var-}" = '' ], главным образом потому, что это избавляет меня от необходимости заключать в двойные кавычки ${var-}, и надоедливый случай значения в $var, которое интерпретируется как опция [ и выдает сообщение об ошибке, когда вы меньше всего этого ожидаете. (В Bash у [[ таких проблем нет; но я предпочитаю придерживаться POSIX Shell, когда могу.)

23
tripleee

Если вы хотите проверить, что переменная не пуста, вы можете сделать это:

if [ -z "$tag" ]; then
    exit 1
fi

Из руководства для test:

-Z STRING

длина STRING равна нулю

Учитывая, что вы используете в сценарии позиционные аргументы, вы также можете проверить количество полученных аргументов, посмотрев на $#.

14
Micah Smith

Никто не предложил вариант :?.

Если вы хотите убедиться, что переменная установлена, а не нуль:

SEARCH_PATH=${DAYS_TO_KEEP:?Must provide DAYS_TO_KEEP.}

Сразу выйдет с кодом 2 и распечатает сообщение:

/entrypoint.sh: line 17: SEARCH_PATH: Must provide DAYS_TO_KEEP.
5
Pav K.

Я не уверен, хотите ли вы определить, является ли переменная unset или empty. Это 2 разные вещи. В частности, переменная может быть установлена, но быть пустой:

$ var=""
$ if [ -z "$var" ]; then echo empty; fi
$ empty

То же самое происходит и здесь:

#!/usr/bin/env bash

set -u
echo $1

Тестовое задание:

$ ./test.sh
./test.sh: line 4: $1: unbound variable
$ ./test.sh ""

$

Или здесь:

#!/usr/bin/env bash

tag=${1?Need a value}
echo $tag

Тестовое задание:

$ ./se.sh
./se.sh: line 3: 1: Need a value
$ ./se.sh ""

$

Другие авторы представили правильные способы обнаружения неустановленной и пустой переменной. Лично мне нравится этот способ обнаружения пустых и неустановленных переменных:

#!/usr/bin/env bash

if [ "$1"A = A ]
then
    echo variable is empty or unset
fi

Тестовое задание:

$ ./empty.sh ""
variable is empty or unset
$ ./empty.sh
variable is empty or unset
$ ./empty.sh 1
$
3
Arkadiusz Drabczyk

Мне скорее понравилось, как Perl использует «die», и в Shell легко сделать нечто подобное. 

# Print (optional) error message and exit
# Usage: die [[msg] exit_status]
die() {
    [[ -n "$1" ]] && echo "$1"
    [[ -n "$2" ]] && exit $2 || exit 1
}

[[ -n "$tag" ]] || die "Need a tag argument.  Use $0 --help for details"

Это предполагает bash или Korn Shell, но может быть преобразовано в классическую Bourne Shell путем изменения [[]] на [].

1
Dan Christian

Следующий тест гарантирует, что переменная имеет значение Null или ей присвоено значение. Двойные кавычки очень важны и должны использоваться!

VAL= # Creates a NULL variable
if [[ -z "$VAL" && "$VAL" = ’’ ]]
then
echo "The VAL variable is NULL"
fi
or
VAL=25
if [[ ! -z "$VAL" && "$VAL" != ’’ ]]
then
echo "The VAL variable is NOT NULL"
fi
0
Pinaki Mukherjee

Используйте сопоставление с образцом, чтобы определить, состоит ли значение только из пробелов:

pattern=$'*( |\t)'
if [[ $1 = $pattern ]]; then
    echo "First parameter has no non-whitespace characters"
    exit 1
fi

Цитирование $'...' упрощает добавление вкладки в строку. Расширенный шаблон *(...) соответствует 0 или более шаблонам внутри скобок (аналогично регулярному выражению ( |\t)*). Шаблон присваивается переменной, потому что = выполняет точное сопоставление строк, если какая-либо часть его правого операнда заключена в кавычки, поэтому мы выполняем кавычки заранее, чтобы упростить установку значения.

0
chepner