Назначение значений по умолчанию для переменных оболочки одной командой в bash
У меня есть множество тестов для переменных в скрипте на bash (3.00), где, если переменная не задана, то присваивается значение по умолчанию, например:
if [ -z "${VARIABLE}" ]; then
FOO='default'
else
FOO=${VARIABLE}
fi
Мне кажется, что существует какой-то синтаксис для выполнения этой операции в одну строку, что-то, напоминающее тернарный оператор. Например:
FOO=${ ${VARIABLE} : 'default' }
(хотя я знаю, что это не будет работать...)
Я сошел с ума или что-то подобное действительно существует?
5 ответ(ов)
Для командных аргументов:
VARIABLE="${1:-$DEFAULTVALUE}"
Эта конструкция присваивает переменной VARIABLE
значение первого аргумента, переданного скрипту, или значение DEFAULTVALUE
, если такой аргумент не был передан. Кавычки предотвращают расщепление слов и обработку символов подстановки (globbing).
Для ответа на ваш вопрос и об всех заменах переменных:
echo "${var}"
echo "Подставляет значение переменной var."
echo "${var:-word}"
echo "Если var пустая или не установлена, вместо неё подставляется слово 'word'. Значение var не изменяется."
echo "${var:=word}"
echo "Если var пустая или не установлена, var получает значение 'word'."
echo "${var:?message}"
echo "Если var пустая или не установлена, сообщение выводится в стандартный поток ошибок. Этот конструк проверяет, что переменные установлены корректно."
echo "${var:+word}"
echo "Если var установлена, вместо неё подставляется слово 'word'. Значение var не изменяется."
Вы можете экранировать все выражение, поставив \
между знаком доллара и остальной частью выражения:
echo "$\{var}"
Вам необходимо использовать значение одной переменной в качестве значения по умолчанию для другой переменной в Bash. Ваш пример с файлом defvalue.sh
показывает, как это сделать.
Вот как работает скрипт:
#!/bin/bash
variable1=$1
variable2=${2:-$variable1}
echo $variable1
echo $variable2
Когда вы запускаете скрипт с двумя аргументами, например:
./defvalue.sh first-value second-value
Вывод будет следующим:
first-value
second-value
В этом случае variable1
получает значение first-value
, а variable2
получает значение second-value
, потому что аргумент был передан.
Однако, если вы выполните скрипт только с одним аргументом:
./defvalue.sh first-value
Вывод будет:
first-value
first-value
Здесь variable1
опять получает значение first-value
, а variable2
получает значение first-value
, так как второй аргумент не был передан, и используется значение variable1
как значение по умолчанию.
Таким образом, вы можете использовать синтаксис ${2:-$variable1}
для задания значения по умолчанию для переменной, основываясь на значении другой переменной.
Для справки, вы можете предоставить сообщение об ошибке следующим образом:
USERNAME=${1:?"Укажите имя пользователя"}
Это отобразит сообщение вроде следующего и выйдет с кодом 1:
./myscript.sh
./myscript.sh: line 2: 1: Укажите имя пользователя
Вот более полный пример всего скрипта:
#!/bin/bash
ACTION=${1:?"Укажите 'action' как 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, но я не уверен, что это переносимо.
Да, возможно цепочечное использование значений по умолчанию, как показано в следующем примере:
DOCKER_LABEL=${GIT_TAG:-${GIT_COMMIT_AND_DATE:-latest}}
Это означает, что если переменная $GIT_TAG
не задана, будет использовано значение переменной $GIT_COMMIT_AND_DATE
. Если же и эта переменная не существует, будет присвоено значение "latest"
. Таким образом, вы можете задавать несколько уровней значений по умолчанию.
Как выводить команды оболочки по мере их выполнения
Замена одной подстроки на другую в shell-скрипте
Как указать приватный SSH-ключ для выполнения команды shell в Git?
Как сделать паузу в shell-скрипте на одну секунду перед продолжением?
Как использовать 'grep' для непрерывного потока?