В чем разница между "$@" и "$*" в 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
Другие вопросы по тегам