Чи дійсний синтаксис "$ {PS1-}" і чим він відрізняється від простого "$ PS1"?


12

Я дивлюся на сценарій, який містить:

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

Цей трейлінг -помиляється на мене трохи тому, що він не здається стандартним синтаксисом Посікса чи Баша. Це якийсь таємничий синтаксис, який існує назавжди, чи це друкарська помилка? Будь-які посилання на стандарти / документи будуть вдячні.

Зазвичай я б це кодував:

if [ "$PS1" ]; then

Що правильніше чи є різниця між ними?

Відповіді:


12

Це, безумовно, синтаксис POSIX . Перефразовуючи:

Використовуючи ${parameter-word}, якщо parameterє

  • встановити, а не нуль, а потім замінити значення parameter,
  • встановити, але null, потім замінити null, і
  • скасувати, потім замінити word.

Приклад сеансу:

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

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

"Нульовий" тут просто означає порожній рядок. На відміну від SQL, наприклад, в оболонках POSIX немає спеціального нульового значення.

Це також задокументовано в розділі "Розширення параметрів" в man bash.


1
Я думаю, що bash і dash man-сторінки неповні, тому що вони не згадують про цей синтаксис (непарне)!
Грегор

1
@Gregor Обидва посібники згадують про це. У посібнику Bash це в абзаці перед списком розширень параметрів, а в посібнику Dash - в абзаці після.
Kusalananda

1
Гаразд, "Опущення товстої кишки ...." Я цього не бачив :(
Грегор

zshце єдина оболонка, про яку я знаю, яка чітко згадує варіанти без товстої кишки, а не просто зазначає, що робить опущення товстої кишки.
чепнер

1
@pts, текст POSIX в значній мірі використовує виключно термін "null", що може пояснити його використання на сторінках man.
ilkkachu

23

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

Якщо пропустити :заповіт, не буде перевірятися, чи значення порожнє, лише чи воно не встановлено чи ні.

Це означає, що ${PS1-}вона розшириться до значення, $PS1якщо воно встановлено, але до порожнього рядка, якщо він порожній або не встановлений. У цьому випадку це точно так само, ${PS1:-}як і рядок після -, також порожній.

Різниця між "${PS1-}"і "$PS1"є незначною, як зазначає @Rakesh Sharma: і те, і інше буде розширюватися до значення $PS1або до порожнього рядка, якщо воно не встановлено. Виняток - коли set -uактивовано, і в цьому випадку розширення невстановлених змінних може спричинити помилку . Значення (порожнє), встановлене за замовчуванням, "${PS1-}"обминає це, розширюючи невстановлене PS1значення до порожнього рядка без помилок.

Це стандартний синтаксис ( виник у оболонці Борна наприкінці 70-х років ), як і пара інших подібних розширень.


А оскільки він був цитований, це те саме, що "$PS1", якщо PS1він порожній, він порожній, а цитати не дають слова повністю зникнути.
ilkkachu

4
Поки set -uце не діє. Коли параметр іменника включений, "$ PS1" => видає помилку. "$ {PS-}" не буде.

@RakeshSharma - це хороший момент. Різний синтаксис може насправді дати різні результати залежно від параметра іменника, тому тест ["$ {parameter-}"], ймовірно, більш правильний!
Грегор

1
@Kusalananda: Зауважте, що ${parameter:-word}буде використано значення, $parameterякщо воно NON-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-}використовується для обходу цього суворого правила. Це працює в обох випадках, так що так, це більш правильний спосіб.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.