Доступ к командной строке 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