Переменные и ввод пользователя

ShellBeginner
Практиковаться сейчас

Введение

Представьте робота-официанта. Статичный робот может говорить всем только одну и ту же фразу: «Здравствуйте, сэр». Динамический робот может спросить ваше имя и сказать: «Здравствуйте, Сара» или «Здравствуйте, Майк».

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

Это важный переход в программировании. Как только скрипт начинает принимать ввод, он перестаёт быть фиксированным примером и становится многоразовым инструментом.

Вы изучите два способа взаимодействия со скриптом:

  1. Спросить и выслушать: скрипт приостанавливается и задаёт вопрос пользователю с помощью read.
  2. Передать записку: вы передаёте данные скрипту в момент запуска с помощью аргументов.

К концу этой лабораторной работы ваш код сможет приветствовать любого человека, а не только World.

Использование read для интерактивного ввода

Начнём с «разговорного» подхода. Скрипт выведет вопрос, а затем будет ждать ответа.

Для этого используется команда read. Представьте, что read говорит: «Остановись, слушай внимательно и жди, пока пользователь что-нибудь введёт».

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

Сначала перейдите в рабочий каталог проекта:

cd ~/project

Создайте новый файл hello.sh с помощью nano:

nano hello.sh

Введите следующий код.
Примечание: мы создаём «коробку» — переменную с именем name, чтобы сохранить ответ пользователя.

#!/bin/bash

echo "What is your name?"
read name
echo "Hello, $name!"

Разберём код:

  • echo "...": скрипт обращается к вам.
  • read name: скрипт ждёт ввод. Всё, что вы напечатаете, будет помещено в «коробку» name.
  • $name: скрипт открывает «коробку». Символ $ позволяет получить значение переменной.

Обратите внимание на разницу между name и $name. name — это имя переменной, когда вы создаёте её или записываете в неё значение. $name означает: «замени это выражение значением, сохранённым в переменной». Такая замена называется подстановкой, или расширением переменной (expansion), и является одним из важнейших механизмов оболочки.

Сохраните файл (Ctrl+O, затем Enter) и выйдите из nano (Ctrl+X).

Запуск интерактивного скрипта

Прежде чем начать взаимодействовать со скриптом, нужно разрешить его запуск. Помните «ключ» из предыдущей лабораторной работы?

Предоставьте файлу право на выполнение:

chmod +x hello.sh

Теперь поговорим со скриптом. Запустите его:

./hello.sh

Скрипт выведет вопрос What is your name?, а затем приостановится. Он будет ждать вашего ответа. Курсор может мигать.

Введите своё имя, например Alice, и нажмите Enter.

What is your name?
Alice
Hello, Alice!

Это называется интерактивным вводом. Такой режим удобен для инструментов, которыми пользуются люди, но плохо подходит для автоматизации. Представьте, что нужно автоматически запустить этот скрипт в 3 часа ночи. Он остановится в ожидании ответа, которого никто не введёт.

Эта особенность важна в реальной эксплуатации. Интерактивные скрипты удобны, когда рядом находится человек, а задания по расписанию, CI-пайплайны и скрипты запуска обычно должны получать неинтерактивный ввод, чтобы выполняться без участия пользователя.

Использование аргументов для неинтерактивного ввода

Чтобы скрипт подходил для автоматизации, нужно передать ему данные до начала выполнения. Тогда ему не придётся приостанавливаться. Для этого используются аргументы.

Представьте аргументы как «почтовый слот» в двери. Вы проходите мимо и сразу опускаете туда сообщение.

В Bash эти почтовые слоты имеют нумерованные имена:

  • $1 — первое слово, введённое после имени скрипта.
  • $2 — второе слово и так далее.

Эти пронумерованные значения называются позиционными параметрами. Оболочка создаёт их автоматически при запуске скрипта. Вам не нужно самостоятельно определять $1: Bash заполняет его данными из командной строки, которая запустила скрипт.

Изменим hello.sh, чтобы он брал имя из первого почтового слота $1, а не задавал вопрос.

Откройте файл:

nano hello.sh

Измените код следующим образом:

#!/bin/bash

name=$1
echo "Hello, $name!"

Строка name=$1 берёт значение из слота $1 и помещает его в «коробку» name. Никаких пауз и вопросов.

Сохраните файл и выйдите из редактора.

Запуск скрипта с аргументами

Теперь скрипт запускается иначе. Вы просто «передаёте» ему имя в момент запуска.

Выполните команду:

./hello.sh LabEx

Здесь LabEx — аргумент. Скрипт получает его как $1 и сразу выводит:

Hello, LabEx!

Попробуйте другое имя:

./hello.sh World

Скрипт сработает мгновенно — без пауз.

Проблема пустого слота

Что произойдёт, если не передать аргумент?

./hello.sh

Вы получите:

Hello, !

Слот $1 был пуст, поэтому «коробка» name тоже оказалась пустой. В следующих лабораторных работах вы научитесь обнаруживать такую ситуацию и выводить сообщение об ошибке. А пока вы успешно создали компактный скрипт, готовый к автоматизации.

Разница между интерактивным вводом и аргументами командной строки имеет фундаментальное значение. Команда read запрашивает данные во время выполнения, а $1 доступен с самого начала. Многие инструменты Unix используют аргументы, потому что их проще автоматизировать, описывать, повторять и объединять с другими командами.

Итоги

Поздравляем! Вы освоили искусство слушать.

В этой лабораторной работе вы изучили:

  1. Интерактивный режим: использование read для диалога с пользователем — удобно для людей.
  2. Режим аргументов: использование $1 для передачи данных во время запуска — удобно для автоматизации.

Вы также узнали, что переменные, такие как $name, — это именованные «коробки», в которых скрипты хранят информацию. Эта концепция лежит в основе всего программирования.