Является ли «$ {PS1-}» допустимым синтаксисом и чем он отличается от простого «$ PS1»?

12

Я смотрю на сценарий, который имеет:

if [ "${PS1-}" ]; then

Этот трейлинг -немного беспокоит меня, потому что он не соответствует стандартному синтаксису Posix или Bash. Это какой-то загадочный синтаксис, который был всегда, или это опечатка? Любые ссылки на стандарты / документы будут приветствоваться.

Обычно я бы написал это:

if [ "$PS1" ]; then

Что является более правильным или есть разница между ними?

Грегор
источник

Ответы:

12

Это определенно синтаксис POSIX . Перефразируя:

Используя ${parameter-word}, если parameterесть

  • установить и не ноль, а затем заменить значение parameter,
  • установить, но ноль, затем заменить ноль, и
  • сбросить, затем заменить word.

Пример сеанса:

$ echo "${parameter-word}"
word
$ parameter=
$ echo "${parameter-word}"

$ parameter=value
$ echo "${parameter-word}"
value

«Нуль» здесь просто означает пустую строку. В отличие от SQL, в оболочках POSIX нет специального нулевого значения.

Это также задокументировано в разделе «Расширение параметров» man bash.

l0b0
источник
1
Я думаю, что man-страницы bash и dash неполные, потому что они не упоминают этот синтаксис (странно)!
Грегор
1
@ Грегор Оба руководства упоминают это. В руководстве по Bash он находится в абзаце перед списком расширений параметров, а в руководстве по Dash - в абзаце после.
Кусалананда
1
ОК, "Опуская двоеточие ...." Я не видел этого :(
Грегор
zshэто единственная оболочка, о которой я знаю, которая явно упоминает варианты без двоеточия, а не просто записывает, что делает пропущение двоеточия.
chepner
1
@pts, текст в POSIX почти полностью использует термин «ноль», что может объяснить его использование на страницах руководства.
ilkkachu
23

Расширение переменной ${parameter:-word}будет использовать значение $parameterif, если оно установлено, и ненулевое (не пустая строка), в противном случае оно будет использовать строку word.

Пропуск :не проверяет, является ли значение пустым, только независимо от того, установлено оно или нет.

Это означает, что ${PS1-}будет расширяться до значения, $PS1если оно установлено, но до пустой строки, если она пуста или не установлена. В этом случае, это точно так же , как ${PS1:-}как строка после -также опорожнить.

Как замечает @Rakesh Sharma, разница между "${PS1-}"и "$PS1"незначительна: оба расширятся до значения $PS1или до пустой строки, если она не задана. Исключением является то, когда set -uактивен, и в этом случае расширение неустановленных переменных может вызвать ошибку . (Пустое) значение по умолчанию, установленное с помощью "${PS1-}"обхода этого, расширяет unset PS1до пустой строки без ошибок.

Это стандартный синтаксис ( возник в оболочке Bourne в конце 70-х годов ), как и пара других подобных расширений.

Kusalananda
источник
И так как он был в кавычках, он такой же, как "$PS1", если PS1он пустой, то он пустой, а кавычки не дают слову полностью исчезнуть.
ilkkachu
4
Пока set -uэто не действует. Когда опция nounset включена, «$ PS1» => выдает ошибку. "$ {PS-}" не будет.
@RakeshSharma, это хороший момент. Различный синтаксис может фактически давать разные результаты в зависимости от опции существительного, поэтому тест ["$ {parameter-}"], вероятно, более корректен!
Грегор
1
@Kusalananda: Обратите внимание, что ${parameter:-word}будет использоваться значение, $parameterесли оно не NULL. Во всех других случаях (что означает: либо установлен, но NULL, либо не установлен), он будет использовать word. Ваша формулировка:if its set or null
@ikkachu: Да, это правильно. Только когда переменные set AND nonnull= = использовать себя. В противном случае ( set but NULL OR unset) => использовать слово.
6

Синтаксис:

${parameter:-word}

и специальная форма:

${parameter-word}

является допустимым синтаксисом в оболочке POSIX , означает использование значения по умолчанию, wordесли parameterоно не установлено или равно нулю.


Обычно, с wordпусто, тогда:

${parameter-}

и:

$parameter

или:

${parameter}

эквивалентны.

Но под действием set -uвсех неустановленных переменных оболочка завершается. ${parameter-}используется для обхода этого строгого правила. Это работает в обоих случаях, так что да, это более правильный путь.

cuonglm
источник