2015-05-06 2 views
5

Я пишу сценарий bash, который принимает некоторые необязательные параметры. Я хочу перевести их и передать их другому сценарию. Тем не менее, я с трудом переношу факультативные параметры изящно.Как передать дополнительные параметры другой команде в сценарии bash?

Вот набросок того, что мне удалось получить работу в псевдокоде:

a.sh:

if arg1 in arguments; then 
    firstArg="first argument" 
fi 
if arg2 in arguments; then 
    secondArg="second argument" 
fi 

./b.sh $firstArg $secondArg "default argument" 

Обратите внимание на пробелы в аргументах.

b.sh:

for arg in "[email protected]" 
do 
    echo $arg 
done 

Я хочу назвать b.sh, необязательно с firstArg и secondArg и аргумент по умолчанию так:

./b.sh $firstArg $secondArg "default argument" 

Проблема с этим состоит в том, что если $firstArg или $secondArg являются строками с пробелами, они будут представлены в виде нескольких аргументов, а выход будет выглядеть примерно так:

first 
argument 
second 
argument 
default argument 

Хорошо, что это легко исправить, давайте захватить всю строку аргументов, добавив кавычки вокруг него, как так:

./b.sh "$firstArg" "$secondArg" "defaultArg" 

Проблема, если, например, firstArg не установлен, это приводит к пустая строка (как она будет интерпретировать "" в качестве параметра), так что на выходе будет что-то вроде:

(blank line here) 
second argument 
defaultArg 

Я также попытался строить строку и передать его в сценарий оболочки, но это не делает похоже, работают таким образом (it int erprets целая строка в качестве аргумента, даже если я добавляю отдельные аргументы с кавычками).

Обратите внимание, что вызов b.sh из моей командной строки с указанными аргументами работает нормально. Есть ли способ имитировать, как это работает из сценария bash?

+1

стороны: Просто потому, что я скопировав свинец и используя '.sh' расширение на исполняемые файлы (то есть файлы с разрешением + x, против которых будет выполняться вызов 'execv()' -family), не означает, что это хорошая идея. В общем, команды в UNIX не должны иметь никаких расширений, независимо от того, предоставлены ли они через сценарий оболочки, скрипт Python, скомпилированный двоичный файл и т. Д. –

+0

Можете ли вы явно разъяснить, используется ли это для кода с помощью '#!/bin/sh' или '#!/bin/bash'? –

+0

Я использую bash. – Andrew

ответ

7

Если вы буквально хотите скопировать все аргументы, приведенные, но добавить еще один:

# this works in any POSIX shell 
./b.sh "[email protected]" defaultArg 

С другой стороны, явно передать firstArg и secondArg, но только если они существуют (обратите внимание, что набор к-ан-пусто -Value считается как "существующие" здесь):

# this works in any POSIX shell 
./b.sh ${firstArg+"$firstArg"} ${secondArg+"$secondArg"} defaultArg 

Если вы хотите рассматривать, как не существует потасовка-ан-пустому стоимости:

# this works in any POSIX shell 
./b.sh ${firstArg:+"$firstArg"} ${secondArg:+"$secondArg"} defaultArg 

Альтернативный подход заключается в создании массива аргументов:

# this requires bash or another shell with arrays and append syntax 
# be sure any script using this starts with #!/bin/bash 
b_args=() 
[[ $firstArg ]] && b_args+=("$firstArg") 
[[ $secondArg ]] && b_args+=("$secondArg") 
b_args+=("default argument") 
./b.sh "${b_args[@]}" 

Если вы хотите что-то с той же гибкостью, как метод массива, но без проблем совместимости, определить функцию; в нем, вы можете безопасно переопределить "[email protected]", не влияя на остальную часть скрипта:

runB() { 
    set -- 
    [ -n "$firstArg" ] && set -- "[email protected]" "$firstArg" 
    [ -n "$secondArg" ] && set -- "[email protected]" "$secondArg" 
    ./b.sh "[email protected]" "default argument" 
} 
+0

Не цитирует '' $ @ "' здесь неправильно? После этого он не станет предметом разрыва слова. Не так ли? – hek2mgl

+0

@ hek2mgl, а? Нет, расщепление слов явно здесь не требуется. –

+0

Хороший ответ! Я не получил вопрос правильно, разместив комментарий. – hek2mgl

1

использовать массив:

args=() 

if [ ... ]; then 
    args+=("first argument") 
fi 

if [ ... ]; then 
    args+=("second argument") 
fi 

./b.sh "${args[@]}" "default argument" 
+0

@EtanReisner Нет, это не так, потому что в примере OP '$ firstArg' не может быть установлен вообще (но используется), но если он будет установлен, он будет установлен в строковый литерал (тот же в приведенном выше фрагменте). –

+0

Ах, я предположил, что это были заполнители для фактических первых и вторых аргументов, а не буквальных строк (в OP, а также здесь), и поскольку вы оставили фактические тесты на самих аргументах, я не заполнил их. не имеет этой проблемы, но, как написано, это также половина решения (и я думаю, что это не совсем правильно). –

+0

Я получаю, откуда вы пришли. Однако OP, дающий './b.sh '$ firstArg" "$ secondArg" defaultArg "' как возможное решение (и описывая его единственную ошибку как прохождение через пустые аргументы, а не вообще не предоставляя их), указывает, что использование литеральных строк «первый аргумент» и «второй аргумент» - это была просто небрежность раньше в вопросе. –

Смежные вопросы