Я пишу очень простой скрипт, который вызывает другой скрипт, и мне нужно передать параметры из моего текущего скрипта в скрипт, который я выполняю.
Например, мой сценарий зовут foo.sh
и называетbar.sh
foo.sh:
bar $1 $2 $3 $4
Как я могу сделать это без явного указания каждого параметра?
bash
command-line-arguments
Fragsworth
источник
источник
Ответы:
Используйте
"$@"
вместо обычного,$@
если вы действительно хотите, чтобы ваши параметры передавались одинаково.Заметим:
источник
'arg with spaces'
для трех примеров. Я был удивлен результатами; надеюсь, вы можете объяснить их../foo.sh "arg with spaces"
и./foo.sh 'arg with spaces'
на 100% идентичны, поэтому я не понимаю, как предложение добавить его в приведенные примеры могло бы помочь.Для баш и других оболочек типа Борна:
источник
$argv:q
будет работать в некоторых вариантах csh.exec java com.myserver.Program "$@"
Это заставит bash выполнить java, а не ждать, пока он завершится. Итак, вы используете на один процесс меньше. Кроме того, если родительский процесс (который запускал ваш скрипт) просматривает его через pid и ожидает, что это будет процесс 'java', некоторые необычные вещи могут прерваться, если вы не выполните exec; exec заставляет Java наследовать тот же pid.args=("$@")
и расширить каждый элемент как отдельное «слово» оболочки ( сродни"$@"
) с"${args[@]}"
."$@"
, например, не получится ли, если в аргументе были пробелы, или нулевые символы, или другие специальные символы?Использование
"$@"
(работает для всех POSIX- совместимых).Из Баш по примеру .
источник
$*
. Я верю, что здесь есть историческая прогрессия;$*
не работал, как задумано, поэтому$@
был изобретен, чтобы заменить его; но поскольку правила цитирования являются тем, чем они являются, двойные кавычки вокруг них все еще требуются (или это вернется к нарушенной$*
семантике).echo "$@"
as,./script.sh a "b c" d
то вы просто получаетеa b c d
вместоa "b c" d
, что очень сильно отличается.echo
получает три аргумента:"a" "b c" "d"
(тогда оболочка объединяет их вместе как часть своего расширения строки). Но если бы вы использовали,for i in "$@"; do echo $i; done
вы бы получилиa⏎b c⏎d
.Я понимаю, что на это хорошо ответили, но вот сравнение между "$ @" $ @ "$ *" и $ *
Содержание тестового скрипта:
Теперь запустите тестовый скрипт с различными аргументами:
источник
Просто подумал, что это может быть немного более полезно при попытке проверить, как аргументы входят в ваш скрипт
источник
$#
""
,''
в качестве аргумента, также, если аргументов не было, он молчит. Я пытался это исправить, но нужен цикл для и счетчик с$#
. Я только добавил это в конце:echo "End of args or received quoted null"
У моего SUN Unix есть много ограничений, даже «$ @» не интерпретируется как нужно. Мой обходной путь - $ {@}. Например,
Кстати, мне нужно было этот конкретный скрипт, потому что мой Unix также не поддерживает grep -r
источник
ksh
Если вы включите
$@
в строку в кавычках другие символы, то при наличии нескольких аргументов поведение будет очень странным, только первый аргумент будет включен в кавычки.Пример:
Урожайность:
Но сначала присваиваем другую переменную:
Урожайность:
источник
"$@"
в bash. Это также помогает проиллюстрировать ключевое различие между$@
и$*
, и почему они оба полезны. Изbash(1)
справочной страницы раздела «Специальные параметры»: «*
- Когда раскрытие происходит в двойных кавычках, оно раскрывается в одно слово со значением каждого параметра […], то"$*"
есть эквивалентно"$1c$2c..."
, гдеc
находится [$IFS
].» И действительно, использование$*
вместо$@
вашего первого примера приведет к получению результатов, идентичных второй версии."$@"
. Снова со страницы руководства: «@
- Когда раскрытие происходит в двойных кавычках, каждый параметр раскрывается в отдельное слово. То"$@"
есть эквивалентно"$1"
"$2"
… Если раскрытие в двойных кавычках происходит внутри слова, расширение первого параметра присоединяется с начальной частью исходного слова, а расширение последнего параметра соединяется с последней частью исходного слова. " ... И действительно, если бы ваш код былbash -c "true foo $@ bar baz"
, то запускайте его какtest.sh one two
бы чистыйbash -c 'true foo one' 'two bar baz'
.$*
, я, кажется, забыл, что он существует ..$@
только набирал обороты, когда я впервые начал писать сценарии оболочки, мне все еще нужно напоминать себе, что он есть. Это было обычным делом увидеть, как они"$*"
используются в сценариях ... тогда автор понимал, что он разбивает все их аргументы вместе, поэтому они пробуют всевозможную сложную чепуху с разделением слов"$*"
или [пере] собирают список аргументов с помощью цикла надshift
тянуть их вниз по одному ... только с помощью$@
решает эту проблему. (Помогает тому, что bash использует ту же мнемонику для доступа к элементам массива:${var[*]}
для них всех как для слова,${var[@]}
для списка слов.)bash -c
способ, который не имеет абсолютно никакого смысла.Иногда вы хотите передать все свои аргументы, но перед ними стоит флаг (например
--flag
)Вы можете сделать это следующим образом:
примечание: чтобы избежать дополнительного разделения полей, вы должны заключить в кавычки
%s
и$@
, и, чтобы избежать единственной строки, вы не можете заключить в кавычки подоболочкуprintf
.источник
Работает нормально, за исключением случаев, когда у вас есть пробелы или экранированные символы. Я не нахожу способ захватить аргументы в этом случае и отправить в ssh внутри скрипта.
Это может быть полезно, но так ужасно
источник
Многие ответы здесь рекомендуют
$@
или$*
с и без кавычек, однако ни один, кажется, не объясняет, что они действительно делают и почему вы должны так поступать. Итак, позвольте мне украсть это превосходное резюме из этого ответа :Обратите внимание, что кавычки имеют все значение и без них оба имеют идентичное поведение.
Для моей цели мне нужно было передать параметры из одного скрипта в другой как есть, и для этого лучшим вариантом является:
Обратите внимание, что нет кавычек и
$@
должно работать в вышеуказанной ситуации.источник
bar "$@"
будет эквивалентноbar "$1" "$2" "$3" "$4"
Обратите внимание, что кавычки важны!
"$@"
,$@
,"$*"
Или$*
будет каждый вести себя немного отличается относительно побега и конкатенации , как описано в этом StackOverflow ответ .Один тесно связанный вариант использования передает все заданные аргументы внутри аргумента, подобного этому:
bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\""
,Я использую вариант ответа @ kvantour для достижения этой цели:
bash -c "bar $(printf -- '"%s" ' "$@")"
источник