(Это расширение моего комментария к ответу Калеба Педерсона - см. Этот ответ для более общего подхода к [@]
против [*]
.)
Когда bash (или любая подобная оболочка) анализируеткомандная строка, она разбивает ее на серию «слов» (которые я буду называть «слова-оболочки», чтобы избежать путаницы позже).Обычно слова-оболочки разделяются пробелами (или другими пробелами), но пробелы могут быть включены в слово-оболочку путем экранирования или цитирования.Разница между [@]
и [*]
массивами в двойных кавычках заключается в том, что "${myarray[@]}"
приводит к тому, что каждый элемент массива обрабатывается как отдельное слово-оболочка, тогда как "${myarray[*]}"
приводит к единственному слову-оболочке свсе элементы массива разделены пробелами (или каким бы ни был первый символ IFS
).
Обычно вам нужно поведение [@]
.Предположим, у нас есть perls=(perl-one perl-two)
и мы используем ls "${perls[*]}"
- это эквивалентно ls "perl-one perl-two"
, который будет искать один файл с именем perl-one perl-two
, что, вероятно, не то, что вы хотели.ls "${perls[@]}"
эквивалентно ls "perl-one" "perl-two"
, который с гораздо большей вероятностью может сделать что-то полезное.
Предоставление списка завершающих слов (которые я буду называть comp-words, чтобы избежать путаницы с shell-словами) для compgen
отличается;опция -W
принимает список слов comp, но он должен быть в форме единственного слова оболочки с comp-словами, разделенными пробелами.Обратите внимание, что параметры команды, которые принимают аргументы всегда (по крайней мере, насколько я знаю), принимают одно слово оболочки - иначе не было бы никакого способа узнать, когда заканчиваются аргументы опции и обычные аргументы команды (/ otherфлажки) начинаются.
Более подробно:
perls=(perl-one perl-two)
compgen -W "${perls[*]} /usr/bin/perl" -- ${cur}
эквивалентно:
compgen -W "perl-one perl-two /usr/bin/perl" -- ${cur}
... что делает то, что вы хотите.С другой стороны,
perls=(perl-one perl-two)
compgen -W "${perls[@]} /usr/bin/perl" -- ${cur}
эквивалентно:
compgen -W "perl-one" "perl-two /usr/bin/perl" -- ${cur}
..., что является полной чепухой: "perl-one" - это единственное слово, прикрепленное к -Флаг W, и первый реальный аргумент - который compgen примет в качестве завершаемой строки - это "perl-two / usr / bin / perl".Я ожидаю, что compgen будет жаловаться, что ему были даны дополнительные аргументы ("-" и все, что в $ cur), но, очевидно, он просто игнорирует их.