Привет. Странный факт - всю неделю с нетерпением ждешь выходных, а когда дождался, щелчок пальцами и снова наступил понедельник. А когда отдыхать-то? В рабочие дни разгребаешь рабочую рутину, в выходные разгребаешь домашнюю рутину.



Вот такой вот замкнутый круг получается. С другой стороны ты всегда находишься при деле, в потоке. Меньше времени остается на нытье и на самокопание. А это уже большой плюс. Окей, поныли и хватит, летсгоу!



Ты тёртый калач и всяко знаешь про специальные переменные со знаком $. Держу пари, знаешь только про базовые и часто используемые, типа $? и $1.



Сегодня рассмотрим еще парочку $@ и $*. Эти специальные переменные по сути выполняют одну и туже задачу: выводят список всех аргументов переданных скрипту. Но естественно есть различия в их использовании.



Голову не грей, теория всегда душная, сейчас на примерах рассмотрим и всё у тебя в голове сложится как надо.



Начнем с $@, накидываем скрипт:



echo "Изучаем \$@"

for arg in $@; do

echo "Аргумент: $arg"

done




Запускаем так:



./script.sh 1 2 '3 with spaces'




На экран выводится:



Изучаем $@

Аргумент: 1

Аргумент: 2

Аргумент: 3

Аргумент: with

Аргумент: spaces




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



А теперь немного переделаем скрипт (добавим кавычки) и запустим с теме же аргументами:



echo "Изучаем \$@ с кавычками"

for arg in "$@"; do

echo "Аргумент: $arg"

done




В этот раз на экран выведется такое:



Изучаем $@ с кавычками

Аргумент: 1

Аргумент: 2

Аргумент: 3 with spaces




Вот! Тут мы получили уже более ожидаемый результат. Массив: {$1, $2, $3}



Теперь про $*



echo "Изучаем \$*"

for arg in $*; do

echo "Аргументы: $arg"

done




После запуска с такими же аргументами:



Изучаем $*

Аргументы: 1

Аргументы: 2

Аргументы: 3

Аргументы: with

Аргументы: spaces




Получаем то же самое, что и с $@ без кавычек. Шило на мыло. А вот если заключить $* в кавычки:



echo "Изучаем \$*"

for arg in "$*"; do

echo "Аргументы: $arg"

done




На экране мы получим:



Изучаем $*

Аргументы: 1 2 3 with spaces




Вот и отличие. Оно небольшое, оно практически ненужное. Но в этом и кроются детали. Все аргументы объединились в одну строку, отделенным символом пробела, заданным в IFS (пробел по умолчанию).



Если это не знать, то легко можно наступить на грабли.



Вот пример как заменить IFS разделитель (пробел на запятую):



echo "Изучаем \$*"

IFS=","

for arg in "$*"; do

echo "Аргументы: $arg"

done




Вывод будет таким:



Изучаем $*

Аргументы: 1,2,3 with spaces




Как «эффект бабочки», забыл поставить кавычки, сломал в будущем логику. Поставил кавычки, сломал другую логику. Куда не ткни, вечно какие-то костыли.



Я конечно сомневаюсь, что ты пользуешься таким высокоуровневым программированием (я не пользуюсь), но порой бывает натыкаешься на чужие скрипты с подобной логикой. И тогда важно не попасть в просак.



А что такое просак, хорошо объясняется в фильме «Жмурки».



Ладно, не смею тебя больше отвлекать. Увидимся. Хорошего понедельника!



tags: #bash #linux



💩 @bashdays