Призначення значень за замовчуванням змінним оболонок однією командою в bash


685

У мене є маса тестів на змінні в сценарії оболонки bash (3.00), де, якщо змінна не встановлена, то вона призначає за замовчуванням, наприклад:

if [ -z "${VARIABLE}" ]; then 
    FOO='default'
else 
    FOO=${VARIABLE}
fi

Здається, я пам'ятаю, що для цього в одному рядку є якийсь синтаксис, що нагадує потрійний оператор, наприклад:

FOO=${ ${VARIABLE} : 'default' }

(хоча я знаю, що не вийде ...)

Я божевільний, чи щось подібне існує?


1
Розділ розширення параметрів оболонки посилання на базову оболонку bash - це хороші вихідні місця: tiswww.case.edu/php/chet/bash/bashref.html#Shell-Expansions .
Kemin Zhou

1
Документація Gnu.org для розширення параметрів оболонки (натяк: ви можете зробити багато інших цікавих речей!)
JDB все ще пам’ятає Моніку

Відповіді:


1228

Насправді близько до того, що ви опублікували:

FOO=${VARIABLE:-default}  # If variable not set or null, use default.

Або, що присвоїть defaultдо VARIABLEа:

FOO=${VARIABLE:=default}  # If variable not set or null, set it to default.

64
Якби я хотів знайти це в документації, для чого б google? Гуглінг із спеціальними символами на зразок $ {: -} не дуже простий.
Джошуа Олсон

20
У відповідь на solarmist: "присвоєння змінної bash за замовчуванням" дозвольте мені перейти на цю сторінку, і пошук сторінки керівництва bash із "змінною дупою"
перевів

57
Зауважте, що він не є специфічним для bash і буде працювати з усією сім'єю оболонок. Це безпечно для загальних сценаріїв.
Jocelyn delalande

16
@solarmist Ключове слово - "розширення параметрів bash", якщо ви хочете дізнатися більше про нього та його супутників.
дулеші

20
Ось більш поглиблене пояснення по темі unix.stackexchange.com/a/122848/2407
jottr

290

Для аргументів командного рядка:

VARIABLE=${1:-DEFAULTVALUE}    

який присвоює VARIABLEзначення першого аргументу, переданого сценарію, або значення, DEFAULTVALUEякщо такого аргументу не було передано.


244

Якщо змінна однакова, то

: "${VARIABLE:=DEFAULT_VALUE}"

призначає DEFAULT_VALUE VARIABLE, якщо не визначено. Подвійні лапки запобігають глобулю та розбиткові слів.

Також дивіться Розділ 3.5.3 Розширення параметрів оболонки в посібнику Bash.


27
Цей хитрий трюк для мене не був очевидним, використовуючи: вбудований ефект без ефекту, щоб з'їсти розширення $ {..}, але залишати набір VARIABLE. До сих пір я робив це: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" і відчував себе невмілим для використання VARIABLE двічі.
дино

Виявляється, ЦЕ НІКОЛИ НЕ ПРАЦЮЄ ДЛЯ БАШ-БУЙЛЬТИННИХ ВАРІАБЛІЙ. Це дуже дуже дивно. Наразі мені відомі такіHISTTIMEFORMAT
Отей

як би я встановив кілька значень за замовчуванням? Я спробував ": $ {VARIABLE: = DEFAULT_VALUE}: $ {VARIABLE2: = DEFAULT_VALUE2}", але це, здається, не працює ...
Ганс

8
@Hans: Двокрапка - це команда (яка нічого не робить), і тому вона потрібна лише один раз. Напр.: ${FOO:=DEFAULT1} ${BAR:=DEFAULT2}
Патрік

36

Навіть ви можете використовувати як значення за замовчуванням значення іншої змінної

маючи файл defvalue.sh

#!/bin/bash
variable1=$1
variable2=${2:-$variable1}

echo $variable1
echo $variable2

запустити ./defvalue.sh first-value second-valueвихід

first-value
second-value

і запустити ./defvalue.sh first-valueвихід

first-value
first-value

28

дивіться тут під 3.5.3 (розширення параметра оболонки)

так у вашому випадку

${VARIABLE:-default}

26

Щоб відповісти на ваше запитання та на всі змінні підміни

echo "$\{var}"
echo "Substitute the value of var."


echo "$\{var:-word}"
echo "If var is null or unset, word is substituted for var. The value of var does not change."


echo "$\{var:=word}"
echo "If var is null or unset, var is set to the value of word."


echo "$\{var:?message}"
echo "If var is null or unset, message is printed to standard error. This checks that variables are set correctly."


echo "$\{var:+word}"
echo "If var is set, word is substituted for var. The value of var does not change."

18

FWIW, ви можете надати повідомлення про помилку так:

USERNAME=${1:?"Specify a username"}

Це відображає повідомлення типу цього і закінчується кодом 1:

./myscript.sh
./myscript.sh: line 2: 1: Specify a username

Більш повний приклад всього:

#!/bin/bash
ACTION=${1:?"Specify 'action' as argv[1]"}
DIRNAME=${2:-$PWD}
OUTPUT_DIR=${3:-${HOMEDIR:-"/tmp"}}

echo "$ACTION"
echo "$DIRNAME"
echo "$OUTPUT_DIR"

Вихід:

$ ./script.sh foo
foo
/path/to/pwd
/tmp

$ export HOMEDIR=/home/myuser
$ ./script.sh foo
foo
/path/to/pwd
/home/myuser
  • $ACTION приймає значення першого аргументу і виходить, якщо порожнім
  • $DIRNAME є другим аргументом і за замовчуванням до поточного каталогу
  • $OUTPUT_DIRє третім аргументом, або $HOMEDIR(якщо вони визначені), інакше, /tmp. Це працює в OS X, але я не впевнений, що він портативний.

17

Тоді є спосіб виразити конструкцію "якщо" більш коротко:

FOO='default'
[ -n "${VARIABLE}" ] && FOO=${VARIABLE}

10

Ось приклад

#!/bin/bash

default='default_value'
value=${1:-$default}

echo "value: [$value]"

збережіть це як script.sh і зробіть його виконуваним. запустіть його без парам

./script.sh
> value: [default_value]

запустіть його парам

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