bash призначити значення за замовчуванням


135

$ {параметр: = word} Призначте значення за замовчуванням. Якщо параметр не встановлений або недійсний, розширення слова присвоюється параметру. Значення параметра замінюється. Позиційні та спеціальні параметри таким чином не можуть бути призначені.

Я думав, що я міг би використовувати цю функцію для написання ${LONG_VARIABLE_NAME:=hello}замість довшого LONG_VARIABLE_NAME=${LONG_VARIABLE_NAME:-hello}, але тепер bash також намагається виконати "привіт", і це дає команду не знайдено. Будь-який спосіб уникнути цього? Або мені доведеться дотримуватися останнього? Чи може хтось навести приклад, коли призначення за замовчуванням насправді корисне?


13
При цитуванні тексту корисно включити посилання на джерело.
Джонатан Райнхарт

Відповіді:


202

Використовуйте двокрапку:

: ${A:=hello}

Двокрапка - це нульова команда, яка нічого не робить і ігнорує її аргументи. Він вбудований у bash, тому новий процес не створюється.


93
Я не можу не помітити, що : ${A:=hello}саме так довго A=${A:-hello}. Також здається, що останній трохи менш езотеричний і його намір більш чіткий. Використання :, яке в основному є неоперативним, здається дивним порівняно з тим, як це робило ОП раніше.
Дан Ліплення

5
@camh: Погоджено. Я бачу, де, якби у вас було багато змінних для ініціалізації до значень за замовчуванням, і вони мають довгі імена, :підхід був би кращим як для набору тексту, так і для читання. Так, це здається областю, де Баш міг би скористатися невеликим вдосконаленням.
Dan Molding

17
@DanMoulding: як щодо : ${VERY_LONG_VARIABLE_NAME:=hello}vs.: VERY_LONG_VARIABLE_NAME=${VERY_LONG_VARIABLE_NAME:-hello}. Я сподіваюся, що ви використовуєте описові імена змінних у своєму коді :)
pihentagy

18
Не тільки коротше, але менш схильний до помилок: VERY_LONG_VARIABLE_NAME=${VERY_LOGN_VARIABLE_NAME:-hello}. На жаль
чепнер

5
Перевагою A=$A:-helloпідходу є те, що його самодокументування під час роботи з set -x. Тобто, завдання буде надруковано так, як A=helloтоді, коли команда null надрукує лише значення ( hello).
Лемпрепарат

107

Перегляньте http://www.tldp.org/LDP/abs/html/parameter-substitution.html для прикладів

${parameter-default}, ${parameter:-default}

Якщо параметр не встановлений, використовуйте за замовчуванням. Після виклику параметр все ще не встановлений.
Обидві форми майже рівнозначні. Додатковий :змінює лише те, коли параметр оголошено, але є нульовим.

unset EGGS
echo 1 ${EGGS-spam}   # 1 spam
echo 2 ${EGGS:-spam}  # 2 spam

EGGS=
echo 3 ${EGGS-spam}   # 3
echo 4 ${EGGS:-spam}  # 4 spam

EGGS=cheese
echo 5 ${EGGS-spam}   # 5 cheese
echo 6 ${EGGS:-spam}  # 6 cheese

${parameter=default}, ${parameter:=default}

Якщо параметр не встановлений, встановіть значення параметра за замовчуванням.
Обидві форми майже рівнозначні. : Змінює лише те, коли параметр був оголошений і є нульовим

# sets variable without needing to reassign
# colons suppress attempting to run the string
unset EGGS
: ${EGGS=spam}
echo 1 $EGGS     # 1 spam
unset EGGS
: ${EGGS:=spam}
echo 2 $EGGS     # 2 spam

EGGS=
: ${EGGS=spam}
echo 3 $EGGS     # 3        (set, but blank -> leaves alone)
EGGS=
: ${EGGS:=spam}
echo 4 $EGGS     # 4 spam

EGGS=cheese
: ${EGGS:=spam}
echo 5 $EGGS     # 5 cheese
EGGS=cheese
: ${EGGS=spam}
echo 6 $EGGS     # 6 cheese

${parameter+alt_value}, ${parameter:+alt_value}

Якщо параметр встановлений, використовуйте alt_value, а інше використовуйте null рядок. Після виклику значення параметра не змінюється.
Обидві форми майже рівнозначні. : Змінює лише те, коли параметр був оголошений і є нульовим

unset EGGS
echo 1 ${EGGS+spam}  # 1
echo 2 ${EGGS:+spam} # 2

EGGS=
echo 3 ${EGGS+spam}  # 3 spam
echo 4 ${EGGS:+spam} # 4

EGGS=cheese
echo 5 ${EGGS+spam}  # 5 spam
echo 6 ${EGGS:+spam} # 6 spam

20

Розширення параметрів значення за замовчуванням часто корисне для сценаріїв збірки, як наведений нижче приклад. Якщо користувач просто викликає сценарій таким, яким він є, Perl не буде вбудований. Користувач повинен явно встановити WITH_PERLзначення, відмінне від "ні", щоб його вбудувати.

$ cat defvar.sh
#!/bin/bash

WITH_PERL=${WITH_PERL:-no}

if [[ "$WITH_PERL" != no ]]; then
    echo "building with perl"
    # ./configure --enable=perl
else
    echo "not building with perl"
    # ./configure
fi

Побудувати без Perl

$ ./defvar.sh
not building with perl

Побудувати за допомогою Perl

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