В чем разница между "$@" и "$*" в Bash?
Мне кажется, что они оба хранят все аргументы командной строки.
Так есть ли разница между ними?
2 ответа
Разница неуловима; "$*"
создает один аргумент, разделенный $IFS
переменная, в то время как "$@"
будет расширяться в отдельные аргументы. В качестве примера рассмотрим:
for i in "$@"; do echo "@ '$i'"; done
for i in "$*"; do echo "* '$i'"; done
Когда запускается с несколькими аргументами:
./testvar foo bar baz 'long arg'
@ 'foo'
@ 'bar'
@ 'baz'
@ 'long arg'
* 'foo bar baz long arg'
Больше подробностей:
http://www.gnu.org/software/bash/manual/bashref.html
$*
Расширяется до позиционных параметров, начиная с единицы. Когда раскрытие происходит в двойных кавычках, оно расширяется до одного слова со значением каждого параметра, разделенного первым символом специальной переменной IFS. То есть "$*" эквивалентно "$1c$2c...", где c - первый символ значения переменной IFS. Если IFS не установлен, параметры разделяются пробелами. Если IFS равен нулю, параметры объединяются без промежуточных разделителей.
$@
Расширяется до позиционных параметров, начиная с единицы. Когда раскрытие происходит в двойных кавычках, каждый параметр раскрывается в отдельное слово. То есть "$@" эквивалентно "$1" "$2" .... Если раскрытие в двойных кавычках происходит внутри слова, расширение первого параметра объединяется с начальной частью исходного слова, и Расширение последнего параметра соединяется с последней частью исходного слова. Когда нет позиционных параметров, "$@" и $@ расширяются до нуля (то есть они удаляются).
Ключевое отличие от моего POV в том, что "$@"
сохраняет исходное количество аргументов. Это единственная форма, которая делает.
Например, если файл my_script содержит:
#!/bin/bash
main()
{
echo 'MAIN sees ' $# ' args'
}
main $*
main $@
main "$*"
main "$@"
### end ###
и я запускаю это так:
my_script 'a b c' d e
Я получу этот вывод:
MAIN sees 5 args
MAIN sees 5 args
MAIN sees 1 args
MAIN sees 3 args