В задании правая часть не должна быть заключена в кавычки, чтобы не допустить разбиения и слияния слов, если только она не содержит пробела.
Эти два одинаковы:
myvar=$var
myvar="$var"
но это не так:
myvar='has space'
myvar=has space
Последний пытается выполнить команду space
с переменной окружения myvar
, установленной в значение has
.
Это означает, что content1
совпадает с content2
, а content3
совпадает с content4
, поскольку они отличаются только в кавычках RHS.
Таким образом, различия сводятся к разнице между $@
и $*
; тот факт, что используются подмассивы, не имеет значения. Цитата из руководства:
(для $*
):
Когда раскрытие происходит в двойных кавычках, оно расширяется до одного слова со значением каждого параметра, разделенного первым символом специальной переменной IFS
.
(для $@
):
Когда раскрытие происходит в двойных кавычках, каждый параметр раскрывается в отдельное слово.
Поскольку вы используете кавычки (как вы почти всегда должны использовать при $@
или $*
), разница в том, что "${*:2}"
- это одна строка, разделенная первым символом IFS
, и "${@:2}"
разворачивается на отдельные слова, пробел отделяется.
* * Пример тысяча сорок-девять:
$ set -- par1 par2 par3 # Set $1, $2, and $3
$ printf '<%s>\n' "${@:2}" # Separate words
<par2>
<par3>
$ printf '<%s>\n' "${*:2}" # Single word, blank separated (default IFS)
<par2 par3>
$ IFS=, # Change IFS
$ printf '<%s>\n' "${*:2}" # Single word, comma separated (new IFS)
<par2,par3>
Что касается того, когда использовать $@
против $*
: как правило, вы почти всегда хотите "$@"
и почти никогда версия без кавычек либо , поскольку последний подвержен расщеплению и смещению слов.
"$*"
полезно, если вы хотите объединить элементы массива в одну строку, как в примере, но, как мне кажется, самый распространенный случай - это итерация по позиционным параметрам в скрипте или функции, и это то, что "$@"
для. См. Также этот Bash Pitfall .