2015-12-07 3 views
3

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

E.g.

java -jar compiler.jar --externs "$externs" 
    --foo "another" --bar "more" 

где я хочу --externs "$externs" быть опущено полностью, если $externs пуст. Есть ли способ сделать это в bash, не прибегая к созданию всей команды со строкой?

+0

Я предполагаю, что это в контексте сценария? – miken32

+0

Да, это в большом скрипте. Еще одна возможность, которую я пытаюсь избежать, - это просто повторить команду в двух ветвях. Это становится волосатым, если есть несколько разных команд, которые нужно опустить. Я думал, что может быть какая-то команда подстановки строк, которая привела к тому, что bash даже не вставлял аргумент. Но я еще не нашел его, если он существует. –

+0

как об этом: http://stackoverflow.com/questions/14763608/use-conditional-in-bash-script-to-check-string-argument – EmilyR

ответ

3

Это то, что ${key:+WORDS} расширения для:

java ... ${externs:+--externs "$externs"} 

Это также общая идиома использовать массив для этой цели:

args=() 
if [[ $externs ]]; then 
    args+=(--externs "$externs") 
fi 

java ... "${args[@]}" 
+0

Этот ответ хорошо написан, и мне нравится ваш подход к массиву. Я думаю, что вам не хватает ':' перед '+'. –

+0

@ChrisMiddleton, требуется ли ':' перед '+', зависит от того, как вы хотите обрабатывать пустые, а не unset, значения; если вы хотите обрабатывать переменную, которая существует, но пуста, как если бы она была отменена, тогда да, это будет ': +'. –

+0

@ChrisMiddleton, ... перечитывая свой вопрос, вы действительно прямо сказали «пусто»; отредактирован соответствующим образом. –

3

Вы можете попробовать

java -jar compiler.jar ${externs:+--externs} "${externs:-}" --foo "another" --bar "more" 

описание, от bash документы

${parameter:-word} 
     Use Default Values. If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is sub‐ 
     stituted. 
    ${parameter:+word} 
     Use Alternate Value. If parameter is null or unset, nothing is substituted, otherwise the expansion of word is substituted. 

Вы могли бы попробовать себя с:

externs="some value" 
printf '%s\n' ${externs:+--externs} "${externs:-}" 

выход

--externs
некоторое значение

Примечание: Я использовал printf здесь проверить случай $externs, содержащий несколько слов, в которых, если процитировать не применяется после расширения переменной, результат будет выглядеть как

--externs
некоторые
стоимость

Поэтому я считаю, что этого должно быть достаточно.

externs= 
echo ${externs:+--externs} "${externs:-}" 

выход: ноль

+0

С точки зрения правильности, мне нечего добавить к этому - это хороший ответ (и немного более параноидальный, связанный с спецификацией POSIX sh, чем мой, который полагается на поведение, которое bash реализует, но не документирует ужасно хорошо) , Тем не менее - что случилось с форматированием? '>' обычно используется для указания того, что текст цитируется; по-видимому, здесь имеет другое значение. –

+0

Спасибо за ваш ответ. Мне особенно нравится использование ': -'. Я выбрал Чарльза только потому, что он был первым и имел решение массива, но здесь есть некоторые аккуратные вещи. Из некоторых экспериментов я вижу, что если 'foo =', то '$ {foo: -}' будет пропущенным параметром, тогда как '$ {foo: -" "}' будет пустой строкой. Круто. –

+0

cool, мне формат '>' просто помогает визуально различать код и вывод. Конечно, всегда полезно, если ваш код переносится –