14

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

14

У меня есть множество тестов для переменных в скрипте на bash (3.00), где, если переменная не задана, то присваивается значение по умолчанию, например:

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

Мне кажется, что существует какой-то синтаксис для выполнения этой операции в одну строку, что-то, напоминающее тернарный оператор. Например:

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

(хотя я знаю, что это не будет работать...)

Я сошел с ума или что-то подобное действительно существует?

5 ответ(ов)

6

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

VARIABLE="${1:-$DEFAULTVALUE}"

Эта конструкция присваивает переменной VARIABLE значение первого аргумента, переданного скрипту, или значение DEFAULTVALUE, если такой аргумент не был передан. Кавычки предотвращают расщепление слов и обработку символов подстановки (globbing).

1

Для ответа на ваш вопрос и об всех заменах переменных:

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}"
0

Вам необходимо использовать значение одной переменной в качестве значения по умолчанию для другой переменной в 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} для задания значения по умолчанию для переменной, основываясь на значении другой переменной.

0

Для справки, вы можете предоставить сообщение об ошибке следующим образом:

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, но я не уверен, что это переносимо.
0

Да, возможно цепочечное использование значений по умолчанию, как показано в следующем примере:

DOCKER_LABEL=${GIT_TAG:-${GIT_COMMIT_AND_DATE:-latest}}

Это означает, что если переменная $GIT_TAG не задана, будет использовано значение переменной $GIT_COMMIT_AND_DATE. Если же и эта переменная не существует, будет присвоено значение "latest". Таким образом, вы можете задавать несколько уровней значений по умолчанию.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь