Розширення параметрів
Очевидною відповіддю є використання однієї зі спеціальних форм розширення параметрів:
: ${STATE?"Need to set STATE"}
: ${DEST:?"Need to set DEST non-empty"}
Або краще (див. Розділ "Позиція подвійних лапок" нижче):
: "${STATE?Need to set STATE}"
: "${DEST:?Need to set DEST non-empty}"
Перший варіант (використовуючи просто ?
) вимагає встановити STATE, але STATE = "" (порожня рядок) добре - не саме те, що ви хочете, але альтернативні та старі позначення.
Другий варіант (за допомогою :?
) вимагає, щоб DEST був встановлений і не порожній.
Якщо ви не вводите повідомлення, оболонка надає повідомлення за замовчуванням.
${var?}
Конструкція переносить назад Version 7 UNIX і Bourne Shell (1978 або близько цього). ${var:?}
Конструкція трохи більш пізні: Я думаю , що це було в System III UNIX близько 1981, але це , можливо, були в ПРБ UNIX до цього. Тому він знаходиться в оболонці Корна і в оболонках POSIX, включаючи спеціально Bash.
Зазвичай це задокументовано на сторінці чоловічої оболонки в розділі під назвою Розширення параметрів . Наприклад, bash
посібник говорить:
${parameter:?word}
Помилка відображення, якщо нульова або не встановлена. Якщо параметр недійсний або не встановлений, розширення слова (або повідомлення для цього ефекту, якщо слова немає), записується на стандартну помилку, а оболонка, якщо вона не є інтерактивною, залишається. В іншому випадку значення параметра замінено.
Колонна команда
Я, мабуть, слід додати, що команда двокрапки просто перевіряє свої аргументи, а потім успішно. Це оригінальне позначення коментаря до оболонки (до ' #
' до кінця рядка). Довгий час сценарії оболонок Борна мали двокрапку як перший символ. Оболонка C читає сценарій і використовує перший символ, щоб визначити, чи це для оболонки C ( #
хеш) або оболонки Борна ( :
двокрапка). Тоді ядро вступило в акт і додало підтримку ' #!/path/to/program
', а оболонка Борна отримала ' #
' коментарів, і конвенція про двокрапку пішла в сторону. Але якщо ви натрапите на сценарій, який починається з двокрапки, тепер ви дізнаєтесь чому.
Позиція подвійних лапок
Блонг запитав у коментарі :
Будь-які думки щодо цієї дискусії? https://github.com/koalaman/shellcheck/isissue/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
рекомендується, має бути виправлено. Я не підтвердив, що він не заперечує проти форми, у якій вираз укладено у подвійні лапки, але є обґрунтованим припущенням, що це було б добре.