В соответствии сэта страница, $@ и $* делают практически одно и то же:
The $@ holds list of all arguments passed to the script.
The $* holds list of all arguments passed to the script.
Просматривая все самые популярные результаты в Google, я не смог найти объяснения, почему существуют два, казалось бы, дублирующих друг друга синтаксиса.
Похоже, в моих сценариях они работают одинаково.
cat foo.sh
#!/bin/bash
echo The parameters passed in are $@
echo The parameters passed in are $*
./foo.sh herp derp
The parameters passed in are herp derp
The parameters passed in are herp derp
- Является ли один вариант более предпочтительным, чем другой?
- Почему существуют две встроенные переменные, выполняющие одну и ту же функцию?
Дополнительные источники
bash.cyberciti.biz
решение1
Они не одинаковы. $*
— это одна строка, тогда как $@
— это фактический массив. Чтобы увидеть разницу, выполните следующий скрипт следующим образом:
> ./test.sh one two "three four"
Сценарий:
#!/bin/bash
echo "Using \"\$*\":"
for a in "$*"; do
echo $a;
done
echo -e "\nUsing \$*:"
for a in $*; do
echo $a;
done
echo -e "\nUsing \"\$@\":"
for a in "$@"; do
echo $a;
done
echo -e "\nUsing \$@:"
for a in $@; do
echo $a;
done
Объяснение и результаты для четырех случаев приведены ниже.
В первом случае параметры рассматриваются как одно длинноецитируетсянить:
Using "$*":
one two three four
Случай 2 (без кавычек) — строка разбивается на слова с помощью for
цикла:
Using $*:
one
two
three
four
Случай 3 — каждый элемент $@ рассматривается как строка в кавычках:
Using "$@":
one
two
three four
Последний случай — он обрабатывает каждый элемент как строку без кавычек, поэтому последний элемент снова делится на for three four
:
Using $@:
one
two
three
four
решение2
Разница заключается в том, как они расширяются.
$*
расширяется до одного аргумента, все элементы которого разделены пробелами (на самом деле это первый символ $IFS
).
$@
расширяется до нескольких аргументов.
Например
#!/bin/bash
echo "With *:"
for arg in "$*"; do echo "<$arg>"; done
echo
echo "With @:"
for arg in "$@"; do echo "<$arg>"; done
$ /tmp/test.sh 1 2 "3 4"
With *:
<1 2 3 4>
With @:
<1>
<2>
<3 4>
решение3
Вы можете просмотретьРуководство для начинающих по Bashдля получения дополнительной информации. Они делают практически то же самое, с разницей в том, как это разделено:
$*
- Расширяется до позиционных параметров, начиная с единицы. Когда расширение происходит в двойных кавычках, оно расширяется до одного слова со значением каждого параметра, разделенного первым символом специальной переменной IFS.
$@
- Расширяется до позиционных параметров, начиная с единицы. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельного слова.
Но если вы не установите IFS
значение, отличное от значения по умолчанию, оно может выглядеть идентично.
решение4
Является ли один вариант более предпочтительным, чем другой?
Короткий ответ: "$@"
.
Если вы используете их без двойных кавычек, они одинаковы. В этом случае нет предпочтений относительно одного. Но я предлагаю вам всегда использовать их с двойными кавычками, если только вы не знаете, что именно вы хотите.
Почему существуют две встроенные переменные, выполняющие одну и ту же функцию?
$*
Между и нет разницы $@
, но "$@"
и "$*"
имеют.
Вы можете увидеть мой ответ вэта почтачтобы увидеть, чем они отличаются.