[email protected] $* - программирование" />

Доступ к командной строке bash args [email protected] $*

Во многих SO-вопросах и bash учебниках я вижу, что я могу обращаться к командам командной строки в сценариях bash двумя способами:

$ ~ >cat testargs.sh 
#!/bin/bash

echo "you passed me" $*
echo "you passed me" [email protected]

Результат:

$ ~> bash testargs.sh arg1 arg2
you passed me arg1 arg2
you passed me arg1 arg2

В чем разница между $* и [email protected]?
Когда следует использовать первое и когда использовать последний?

Ответ 1

Разница возникает при цитировании специальных параметров. Позвольте мне проиллюстрировать различия:

$ set -- "arg  1" "arg  2" "arg  3"

$ for word in $*; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in [email protected]; do echo "$word"; done
arg
1
arg
2
arg
3

$ for word in "$*"; do echo "$word"; done
arg  1 arg  2 arg  3

$ for word in "[email protected]"; do echo "$word"; done
arg  1
arg  2
arg  3

еще один пример важности цитирования: обратите внимание, что между "arg" и числом есть 2 пробела, но если я не могу процитировать $word:

$ for word in "[email protected]"; do echo $word; done
arg 1
arg 2
arg 3

а в bash, "[email protected]" - это список по умолчанию для перебора:

$ for word; do echo "$word"; done
arg  1
arg  2
arg  3

Ответ 2

Хорошая удобная обзорная таблица из Bash Hackers Wiki:

$* versus $@ table

где c в третьей строке - первый символ $IFS, разделитель внутренних полей; переменная окружения.

Если аргументы должны храниться в переменной скрипта, и ожидается, что аргументы будут содержать пробелы, я искренне рекомендую использовать трюк "$*" с внутренним разделителем полей $IFS установленным в tab.

Ответ 3

$*

Расширяется до позиционных параметров, начиная с одного. Когда расширение происходит в двойных кавычках, оно расширяется до одного слова со значением каждого параметра, разделенным первым символом специальная переменная IFS. То есть "$ *" эквивалентно "$ 1c $2c...", где c - первый символ значения переменной IFS. Если IFS не задан, параметры разделены пробелами. Если IFS имеет значение NULL, параметры соединяются без промежуточных разделителей.

[email protected]

Расширяется до позиционных параметров, начиная с одного. Когда расширение происходит в двойных кавычках, каждый параметр расширяется до отдельное слово. То есть, "$ @" эквивалентно "$ 1" "$ 2"... Если двойное кавычное расширение происходит внутри слова, расширение первый параметр соединяется с начальной частью оригинала слово, а расширение последнего параметра соединяется с последним часть оригинального слова. Когда нет позиционных параметров, "$ @" и [email protected]развернуть до нуля (т.е. удаляются).

Источник: Bash человек

Ответ 4

[email protected]совпадает с $*, но каждый параметр представляет собой строку с кавычками, то есть параметры передаются без изменений, без интерпретации или расширения. Это означает, среди прочего, что каждый параметр в списке аргументов рассматривается как отдельное слово.

Конечно, нужно указывать "$ @".

http://tldp.org/LDP/abs/html/internalvariables.html#ARGLIST

Ответ 5

Этот пример let может выделить разницу между "at" и "asterix", когда мы их используем. Я объявил два массива "фрукты" и "овощи"

fruits=(apple pear plumm peach melon)            
vegetables=(carrot tomato cucumber potatoe onion)

printf "Fruits:\t%s\n" "${fruits[*]}"            
printf "Fruits:\t%s\n" "${fruits[@]}"            
echo + --------------------------------------------- +      
printf "Vegetables:\t%s\n" "${vegetables[*]}"    
printf "Vegetables:\t%s\n" "${vegetables[@]}"    

Смотрите следующий результат, код выше:

Fruits: apple pear plumm peach melon
Fruits: apple
Fruits: pear
Fruits: plumm
Fruits: peach
Fruits: melon
+ --------------------------------------------- +
Vegetables: carrot tomato cucumber potatoe onion
Vegetables: carrot
Vegetables: tomato
Vegetables: cucumber
Vegetables: potatoe
Vegetables: onion