Bash: как установить переменную из аргумента и со значением по умолчанию
Довольно ясно, что при использовании сценариев с оболочками такого рода вещи можно выполнить огромным количеством способов (больше, чем большинство языков программирования) из-за всех различных методов и программ расширения переменных, таких как test
и [
и [[
и т.д.
Сейчас я просто ищу
DIR=$1 or .
Значение, моя переменная DIR должна содержать либо то, что указано в первом arg, либо в текущем каталоге.
В чем разница между этим и DIR=${1-.}
?
Я считаю, что синтаксис дефиса запутан, и искать более читаемый синтаксис.
Почему я не могу это сделать?
DIR="$1" || '.'
Я предполагаю, что это означает: "если $1 пуст, назначение все еще работает (DIR становится пустым), поэтому неверная команда". "никогда не выполняется".
Ответы
Ответ 1
Здесь я вижу несколько вопросов.
-
"Могу ли я написать то, что на самом деле отражает эту логику"
Да. Есть несколько способов сделать это. Здесь один:
if [[ "$1" != "" ]]; then
DIR="$1"
else
DIR=.
fi
-
"В чем разница между этим и DIR=${1-.}
?"
Синтаксис ${1-.}
расширяется до .
, если $1
не установлен, но расширяется как $1
, если $1
установлен, даже если $1
установлен в пустую строку.
Синтаксис ${1:-.}
расширяется до .
, если $1
не установлен или установлен в пустую строку. Он расширяется, как $1
, только если $1
установлен на что-то другое, чем пустая строка.
-
"Почему я не могу это сделать? DIR="$1" || '.'
"
Потому что это bash, а не perl или ruby или какой-либо другой язык. (Простите мою хрупкость.)
В bash, ||
отделяет целые команды (технически он отделяет конвейеры). Он не разделяет выражения.
So DIR="$1" || '.'
означает "выполнить DIR="$1"
, и если это завершение с ненулевым кодом выхода, выполните '.'
".
Ответ 2
Как насчет этого:
DIR=.
if [ $# -gt 0 ]; then
DIR=$1
fi
$#
- количество аргументов, присвоенных script, а -gt
означает "больше, чем", поэтому вы в основном устанавливаете значение DIR
на значение по умолчанию, и если пользователь указал аргумент, тогда вместо этого вы установите DIR
.
Ответ 3
Я использую простую вспомогательную функцию, чтобы такие задания выглядели чище. Функция ниже принимает любое количество аргументов, но возвращает первый, который не является пустой строкой.
default_value() {
# Return the first non-empty argument
while [[ "$1" == "" ]] && [[ "$#" -gt "0" ]]; do
shift
done
echo $1
}
x=$(default_value "$1" 0)