Например, если вы позвоните, ./someScript.sh foo barто $@будет равно foo bar.
Если вы делаете:
./someScript.sh foo bar
а затем внутри someScript.shссылки:
umbrella_corp_options "$@"
это будет передаваться umbrella_corp_optionsс каждым отдельным параметром, заключенным в двойные кавычки, что позволяет получать параметры с пробелом от вызывающей стороны и передавать их дальше.
$ @ является особенным, если написано в двойных кавычках. Тогда это приведет к списку значений в кавычках, в вашем случае, trusktr, с тремя аргументами: «foo», «bar» и «boo far».
Alfe
4
Хотя это обычно бывает, $@вовсе не обязательно исходить от параметров, получаемых в сценарий ... например, set a b "x y"; printf '(%s)' "$@"выходы(a)(b)(x y)
Peter.O
Мне больше нравится ответ Алфе, потому что он дает главное различие между $@и$*
donleyp
106
$@это почти то же самое $*, что означает «все аргументы командной строки». Они часто используются для простой передачи всех аргументов другой программе (таким образом, формируя оболочку вокруг этой другой программы).
Разница между этими двумя синтаксисами проявляется, когда у вас есть аргумент с пробелами в нем (например) и $@в двойных кавычках:
wrappedProgram "$@"# ^^^ this is correct and will hand over all arguments in the way# we received them, i. e. as several arguments, each of them# containing all the spaces and other uglinesses they have.
wrappedProgram "$*"# ^^^ this will hand over exactly one argument, containing all# original arguments, separated by single spaces.
wrappedProgram $*# ^^^ this will join all arguments by single spaces as well and# will then split the string as the shell does on the command# line, thus it will split an argument containing spaces into# several arguments.
Пример: вызов
wrapper "one two three" four five "six seven"
приведет к:
"$@": wrappedProgram "one two three" four five "six seven"
"$*": wrappedProgram "one two three four five six seven"
^^^^ These spaces are part of the first
argument and are not changed.
$*: wrappedProgram one two three four five six seven
Они не одинаковы, и man-страница ясно о побочных эффектах $ * при использовании IFS, который не обязательно является пробелом. (Если бы они были одинаковыми, не было бы никакого смысла, кроме как совместимости, возможно, предлагать оба.)
jørgensen
6
Нет, они не. И я сказал так двумя строками ниже: «Разница между
этими
2
Alfe, добавление Кристоффером этого единственного слова «почти», чертовски изменило ситуацию, не жертвуя какой-либо краткостью или читабельностью. На самом деле я проголосовал за этот ответ (в отличие от принятого) именно из-за того тонкого акцента разницы ... - прежде чем понять, что он был почти против вашей воли! ;)
Сз.
Я думаю, что это слово имело огромное значение для людей, которые выносят вердикт сразу после прочтения первого предложения ;-), и это никогда не было против моей воли. Я действительно хотел бы написать также для этих людей.
Alfe
Очень непонятно wrappedProgram "$*"-> separated by single spaces.но во втором примере они не разделены пробелами.
Феликс Домбек
36
Это аргументы командной строки, где:
$@= сохраняет все аргументы в списке строк $*= сохраняет все аргументы в виде одной строки $#= сохраняет количество аргументов
(Вышеупомянутая неточность, упомянутая @iruvar, была исправлена.)
Матин Улхак
13
Использование чистых $@средств в большинстве случаев «причиняет столько вреда программисту, сколько вы можете», потому что в большинстве случаев это приводит к проблемам с разделением слов, пробелами и другими символами в аргументах.
В (угаданном) 99% всех случаев требуется заключить его в ": "$@"это то, что может быть использовано для надежного перебора аргументов.
Расширяется до позиционных параметров, начиная с единицы. Когда раскрытие происходит в двойных кавычках, каждый параметр раскрывается в отдельное слово. То есть "$ @" эквивалентно "$ 1" "$ 2" .... Если раскрытие в двойных кавычках происходит внутри слова, расширение первого параметра объединяется с начальной частью исходного слова, и Расширение последнего параметра объединяется с последней частью исходного слова. Когда позиционные параметры отсутствуют, «$ @» и $ @ расширяются до нуля (то есть они удаляются).
Вкратце, $@расширяется до позиционных аргументов, передаваемых от вызывающей стороны либо к функции, либо к сценарию . Его значение зависит от контекста : внутри функции оно распространяется на аргументы, передаваемые такой функции. Если он используется в скрипте (а не в области действия функции), он распространяется на аргументы, передаваемые такому скрипту.
Теперь еще одной темой, которая имеет первостепенное значение при понимании того, как $@ведет себя в оболочке, является разделение слов . Оболочка разделяет токены на основе содержимого IFSпеременной. Значением по умолчанию является \t\n; то есть, пробел, табуляция и новая строка.
Расширение "$@"дает вам нетронутую копию переданных аргументов. Однако расширение $@будет не всегда. Более конкретно, если аргументы содержат символы из IFS, они будут разделены.
Большую часть времени вы хотите использовать "$@", а не $@.
Ответы:
$@
это все параметры, переданные в сценарий.Например, если вы позвоните,
./someScript.sh foo bar
то$@
будет равноfoo bar
.Если вы делаете:
а затем внутри
someScript.sh
ссылки:это будет передаваться
umbrella_corp_options
с каждым отдельным параметром, заключенным в двойные кавычки, что позволяет получать параметры с пробелом от вызывающей стороны и передавать их дальше.источник
someScript.sh foo bar "boo far"
?$@
вовсе не обязательно исходить от параметров, получаемых в сценарий ... например,set a b "x y"; printf '(%s)' "$@"
выходы(a)(b)(x y)
$@
и$*
$@
это почти то же самое$*
, что означает «все аргументы командной строки». Они часто используются для простой передачи всех аргументов другой программе (таким образом, формируя оболочку вокруг этой другой программы).Разница между этими двумя синтаксисами проявляется, когда у вас есть аргумент с пробелами в нем (например) и
$@
в двойных кавычках:Пример: вызов
приведет к:
источник
wrappedProgram "$*"
->separated by single spaces.
но во втором примере они не разделены пробелами.Это аргументы командной строки, где:
$@
= сохраняет все аргументы в списке строк$*
= сохраняет все аргументы в виде одной строки$#
= сохраняет количество аргументовисточник
Использование чистых
$@
средств в большинстве случаев «причиняет столько вреда программисту, сколько вы можете», потому что в большинстве случаев это приводит к проблемам с разделением слов, пробелами и другими символами в аргументах.В (угаданном) 99% всех случаев требуется заключить его в
"
:"$@"
это то, что может быть использовано для надежного перебора аргументов.источник
for a in start_token "$@" end_token; do something_with "$a"; done
:-)Из руководства:
источник
Смысл.
Вкратце,
$@
расширяется до позиционных аргументов, передаваемых от вызывающей стороны либо к функции, либо к сценарию . Его значение зависит от контекста : внутри функции оно распространяется на аргументы, передаваемые такой функции. Если он используется в скрипте (а не в области действия функции), он распространяется на аргументы, передаваемые такому скрипту.Разделение слов.
Теперь еще одной темой, которая имеет первостепенное значение при понимании того, как
$@
ведет себя в оболочке, является разделение слов . Оболочка разделяет токены на основе содержимогоIFS
переменной. Значением по умолчанию является\t\n
; то есть, пробел, табуляция и новая строка.Расширение
"$@"
дает вам нетронутую копию переданных аргументов. Однако расширение$@
будет не всегда. Более конкретно, если аргументы содержат символы изIFS
, они будут разделены.Большую часть времени вы хотите использовать
"$@"
, а не$@
.источник