В чем разница между $ {@: 2} и $ {*: 2} в этих случаях? - PullRequest
0 голосов
/ 04 июля 2018

Учитывая следующий код в bash:

filename=${1} 
content1=${@:2}
content2="${@:2}"
content3=${*:2}
content4="${*:2}"
echo  "${content1}" > "${filename}"
echo   "${content2}" >> "${filename}"
echo  "${content3}" >> "${filename}"
echo   "${content4}" >> "${filename}"

Какая разница между "содержанием"? Когда я увижу разницу? Какой лучший способ сохранить контент, который я получаю и почему?

Ответы [ 2 ]

0 голосов
/ 04 июля 2018

В задании правая часть не должна быть заключена в кавычки, чтобы не допустить разбиения и слияния слов, если только она не содержит пробела.

Эти два одинаковы:

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 .

0 голосов
/ 04 июля 2018

Разница лишь в том, что использование $* приведет к объединению аргументов с первым символом IFS, тогда как $@ приведет к объединению аргументов с одним пробелом (независимо от значения IFS):

$ set a b c
$ IFS=-
$ c1="$*"
$ c2="$@"
$ echo "$c1"
a-b-c
$ echo "$c2"
a b c

Кавычки здесь не особенно важны, так как расширения в правой части назначения не подлежат разбиению по словам или расширению пути; content1 и content2 всегда должны быть идентичны, как и content3 и content4.

Что лучше, зависит от того, что вы хотите .

...