Назначение значений по умолчанию для переменных оболочки с помощью одной команды в bash


690

У меня есть целая куча тестов на переменные в сценарии оболочки 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 .
Кемин Чжоу

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

Ответы:


1232

Очень близко к тому, что вы опубликовали, на самом деле:

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? Поиск в Google специальных символов, таких как $ {: -}, не очень прост.
Джошуа Олсон

20
В ответ на solarmist: «bash переменное назначение по умолчанию» разрешило мне перейти на эту страницу, и поиск страницы справочника bash с «variable ass»
привел

57
Обратите внимание, что это не зависит от bash и будет работать со всем семейством оболочек. Это безопасно для generic-скриптов.
Джоселин Делаланде

16
@solarmist Ключевое слово «расширение параметров bash», если вы хотите узнать больше о нем и его компаньонах.
дулеши,

20
Вот более подробное объяснение по теме unix.stackexchange.com/a/122848/2407
jottr

290

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

VARIABLE=${1:-DEFAULTVALUE}    

который присваивает VARIABLEзначение 1-го аргумента, переданного сценарию, или значение, DEFAULTVALUEесли такой аргумент не был передан.


245

Если переменная такая же, то

: "${VARIABLE:=DEFAULT_VALUE}"

назначает DEFAULT_VALUE для VARIABLE, если не определено. Двойные кавычки предотвращают сбои и разбиение слов.

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


27
Этот хитрый трюк не был очевиден для меня, используя встроенную команду: no-effect, чтобы съесть расширение $ {..} НО, оставляя VARIABLE установленным. До сих пор я делал это: VARIABLE = "$ {VARIABLE: -DEFAULT_VALUE}" и чувствовал себя глупо из-за использования VARIABLE дважды.
Дино

Оказывается, ЭТО НЕ ВСЕГДА РАБОТАЕТ ДЛЯ BASH-BUILTIN ПЕРЕМЕННЫХ. Это очень очень странно. В настоящее время те, которые мне известныHISTTIMEFORMAT
Otheus

Как бы я установить несколько значений по умолчанию? Я пытался ": $ {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.