Расширение параметра
Очевидный ответ - использовать одну из специальных форм расширения параметров:
: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}
Или лучше (см. Раздел «Положение двойных кавычек» ниже):
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Первый вариант (с использованием just ?
) требует установки STATE, но STATE = "" (пустая строка) в порядке - не совсем то, что вы хотите, но альтернативная и более старая нотация.
Второй вариант (использование :?
) требует, чтобы DEST был установлен и не был пустым.
Если вы не укажете сообщение, оболочка предоставит сообщение по умолчанию.
${var?}
Конструкция переносит обратно Version 7 UNIX и Bourne Shell (1978 или около этого). Эта ${var:?}
конструкция немного новее: я думаю, что она была в System III UNIX примерно в 1981 году, но до этого она могла быть в PWB UNIX. Поэтому он находится в оболочке Korn и в оболочках POSIX, включая, в частности, Bash.
Обычно это документируется на справочной странице оболочки в разделе под названием « Расширение параметров» . Например, bash
руководство говорит:
${parameter:?word}
Ошибка дисплея, если ноль или не установлен. Если параметр равен нулю или не задан, расширение слова (или сообщение на этот счет, если слово отсутствует) записывается в стандартную ошибку, и оболочка, если она не является интерактивной, завершается. В противном случае значение параметра подставляется.
Колонское командование
Я, вероятно, должен добавить, что команда двоеточия просто оценивает свои аргументы и затем успешно. Это оригинальная запись комментария оболочки (перед ' #
' до конца строки). Долгое время сценарии оболочки Bourne имели двоеточие в качестве первого символа. Оболочка C будет читать сценарий и использовать первый символ, чтобы определить, относится ли он к оболочке C ( #
хэш ') или к оболочке Борна ( :
двоеточие'). Затем ядро приняло участие и добавило поддержку комментариев ' #!/path/to/program
', а оболочка Bourne получила ' #
', и соглашение о двоеточии ушло на второй план. Но если вы столкнетесь со сценарием, который начинается с двоеточия, теперь вы будете знать, почему.
Положение двойных кавычек
blong спросил в комментарии :
Есть мысли по поводу этой дискуссии? https://github.com/koalaman/shellcheck/issues/380#issuecomment-145872749
Суть обсуждения такова:
… Однако, когда я shellcheck
это (с версией 0.4.1), я получаю это сообщение:
In script.sh line 13:
: ${FOO:?"The environment variable 'FOO' must be set and non-empty"}
^-- SC2086: Double quote to prevent globbing and word splitting.
Любой совет, что мне делать в этом случае?
Краткий ответ «делай как shellcheck
подсказывает»:
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Чтобы проиллюстрировать почему, изучите следующее. Обратите внимание, что :
команда не отображает свои аргументы (но оболочка оценивает аргументы). Мы хотим видеть аргументы, поэтому код ниже использует printf "%s\n"
вместо :
.
$ mkdir junk
$ cd junk
$ > abc
$ > def
$ > ghi
$
$ x="*"
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
abc
def
ghi
$ unset x
$ printf "%s\n" ${x:?You must set x} # Careless; not recommended
bash: x: You must set x
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
bash: x: You must set x
$ x="*"
$ printf "%s\n" "${x:?You must set x}" # Careful: should be used
*
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
abc
def
ghi
$ x=
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$ unset x
$ printf "%s\n" ${x:?"You must set x"} # Not quite careful enough
bash: x: You must set x
$
Обратите внимание, что значение in $x
расширяется до первого, *
а затем списка имен файлов, когда общее выражение не в двойных кавычках. Это то, что shellcheck
рекомендуется исправить. Я не проверял, что он не возражает против формы, в которой выражение заключено в двойные кавычки, но разумно предположить, что все будет в порядке.