Другие ответы охватывают вашу настоящую проблему. Но одно стоит сказать больше о том, как $*
и [email protected]
отличаются расширением при двойном цитировании. tl; dr Вы почти всегда хотите "[email protected]"
.
"$*"
расширяется до одной строка, содержащей все параметры с первым символом в IFS
между ними. На практике это обычно означает, что все параметры являются одной строкой, разделенной пробелами. Итак, если ваши параметры: file1.txt
, file2.txt
и file3.txt
, то "$*"
руки, которые соответствуют петле как одна вещь, а именно file1.txt file2.txt file3.txt
. Это одно, конечно, не существует как таковое.
"[email protected]"
расширяет до каждый из параметров, по одному, рассматривается как одно слово «слово». Это хорошо, потому что он будет обрабатывать file1.txt
, file2.txt
и file3.txt
из предыдущего примера правильно, так как три предмета. Цикл будет принимать их правильно по одному за раз. Кроме того, "[email protected]"
хорош, так как даже если ваши имена файлов имеют пробелы в них, вы получите правильное поведение, так как цикл будет обрабатываться, например. filename 1
, filename 2
, filename 2 and a half
как три предмета, один за другим. (Обычно оболочка рассматривает пространство как маркировка конца слова, так filename 1
будет выглядеть два пунктов к оболочке, filename
и 1
.
Когда они не указаны как [email protected]
и $*
расширить слова все позиционные параметры. Таким образом, в этом случае они фактически идентичны (и плохая идея, так как они не защищают вас от странно названных файлов).
Здесь есть хорошая визуализация всех возможностей: http://wiki.bash-hackers.org/scripting/posparams#mass_usage.
Подробнее см. Здесь о различиях между '$ *' и '$ @': http://mywiki.wooledge.org/BashGuide/Parameters#Special_Parameters_and_Variables. Это тонкий, но очень важный для сценариев оболочки. – Telemachus