Скажем, у меня есть сценарий:
some-command "$var1" "$var2" ...
И, в случае, если var1
это пусто, я бы предпочел, чтобы он был заменен ничем вместо пустой строки, чтобы выполняемая команда была:
some-command "$var2" ...
и нет:
some-command '' "$var2" ...
Есть ли более простой способ, чем тестирование переменной и ее условное включение?
if [ -n "$1" ]; then
some-command "$var1" "$var2" ...
# or some variant using arrays to build the command
# args+=("$var1")
else
some-command "$var2" ...
fi
Есть ли подстановка параметров, которая может расширяться до нуля в bash, zsh и т. П.? Я мог бы все еще хотеть использовать globbing в остальных аргументах, поэтому отключение этого и снятие кавычек с переменной не вариант.
man
странице? (-;Ответы:
У Posix-совместимых оболочек и Bash есть
${parameter:+word}
:Так что вы можете просто сделать:
и должны
var1
быть проверены и"$var1"
использоваться, если оно установлено и не пусто (с обычными правилами двойных кавычек). В противном случае это расширяется в ничто. Обратите внимание, что здесь указана только внутренняя часть, а не вся.То же самое работает и в Zsh. Вы должны повторить переменную, чтобы она не была идеальной, но она работает именно так, как вы хотели.
Если вы хотите, чтобы переменная set-but-empty расширялась до пустого аргумента, используйте
${var1+"$var1"}
вместо этого.источник
word
часть.:+
и+
.sh
/dash
для потенциальных сценариев chokepoint, поэтому всегда ценю, когда кто-то показывает, как это возможно, не прибегая к Bash.Вот что
zsh
делает по умолчанию, когда вы опускаете кавычки:Фактически, единственная причина, по которой вам все еще нужны кавычки в zsh вокруг раскрытия параметров, состоит в том, чтобы избежать такого поведения (пустого удаления), поскольку у
zsh
него нет других проблем, которые влияют на другие оболочки, когда вы не заключаете в кавычки расширения параметров (неявный split + Glob) .Вы можете сделать то же самое с другими POSIX-подобными оболочками, если отключите split и glob:
Теперь я бы сказал, что если ваша переменная может иметь значение 0 или 1, это должен быть массив, а не скалярная переменная, и используйте:
А использование
var1=(value)
приvar1
должен содержать одно значение,var1=('')
когда она содержит один пустое значение, иvar1=()
когда она не содержит не значение.источник
Я столкнулся с этим, используя rsync в bash-скрипте, который запускал команду с или без
-n
переключения для пробного запуска . Оказывается, что rsync и ряд команд gnu принимают''
в качестве действительного первого аргумента и действуют иначе, чем если бы их не было.Отладка заняла довольно много времени, поскольку нулевые параметры почти полностью невидимы.
Кто-то из списка rsync показал мне способ избежать этой проблемы, а также значительно упростил мое кодирование. Если я правильно понимаю, это вариант последнего предложения @ Stéphane Chazelas.
Создайте аргументы вашей команды в нескольких отдельных переменных. Они могут быть установлены в любом порядке или логике, которые подходят для проблемы.
Затем, в конце, используйте переменные для создания массива со всем на своем месте и используйте его в качестве аргументов для фактической команды.
Таким образом, команда выполняется только в одном месте кода, а не повторяется для каждого варианта аргументов.
Любая пустая переменная просто исчезает при использовании этого метода.
Я знаю, что использование eval очень неодобрительно. Я не помню всех деталей, но мне, кажется, нужно, чтобы все работало таким образом - что-то, что связано с обработкой параметров со встроенным пробелом.
Пример:
источник