Скрипт получает аргументы уже разделёнными, по одному слову на аргумент. Что именно он получил, покажет args.sh.
Всё, что стоит в команде после имени скрипта, bash делит на аргументы — по пробелам вне кавычек — и передаёт скрипту. Внутри скрипта аргументы лежат в позиционных параметрах: $1 — первый, $2 — второй, и так далее, а $# — сколько их всего. args.sh печатает $# и каждый аргумент в угловых скобках, чтобы были видны его границы.
Посмотри, что получает скрипт
В ~/args-lab запусти args.sh трижды: с именем в кавычках, с тем же именем без кавычек и совсем без аргументов.
Сначала предположи
Сколько аргументов насчитает args.sh в первой команде, где "my file.txt" в кавычках?
Теперь начни упражнение, выполни команду и сверь прогноз с выводом.
Кавычки при вызове сделали своё дело: args.sh получил my file.txt одним аргументом. Дальше всё решает сам скрипт. args.sh перебирает аргументы так: for a in "$@". Цикл for выполняет команды между do и done для каждого слова из списка после in, и переменная a по очереди получает каждое слово. "$@" в двойных кавычках — особая запись: все аргументы скрипта, каждый отдельным словом, ровно как их передали.
report.sh пишет for f in $@ — без кавычек. Тогда bash подставляет аргументы и снова режет их по пробелам, как $dir без кавычек в уроке о скриптах. Ту же ошибку повторяет wc -l $f внутри цикла. Для вызова с "my file.txt" notes.txt разница такая:
| Запись в скрипте | Какие слова получит цикл |
|---|---|
"$@" |
my file.txt, notes.txt |
$@ или $* |
my, file.txt, notes.txt |
"$*" |
my file.txt notes.txt — одно слово |
Один аргумент подставляют как "$1", все — как "$@", а переменную внутри цикла — тоже в кавычках: wc -l "$f".