bash built-in scripting

read

Чтение строки из стандартного ввода в переменную — встроенная команда bash (bash built-in)

⚙️ bash built-in — встроена в оболочку, не является внешней утилитой

Описание

read — встроенная команда оболочки Bash (bash built-in), которая читает одну строку из стандартного ввода (stdin) и сохраняет её в переменную. В отличие от внешних утилит (ls, grep, tar), read реализована непосредственно внутри bash и не имеет отдельного исполняемого файла в файловой системе.

Главное применение — интерактивный ввод в bash-скриптах. Флаг -p "Prompt: " выводит приглашение пользователю без перевода строки: скрипт выдаёт подсказку и ждёт ввода. В уроках 27 и 30 read -p используется для запроса пути, адреса или имени файла перед обработкой.

По умолчанию read сохраняет прочитанную строку в переменную REPLY (если переменная не указана). Разделителем слов служит содержимое переменной IFS (по умолчанию: пробел, табуляция, перевод строки).

Синтаксис

read [OPTIONS] [VARNAME...] # Простой интерактивный запрос read -p "Enter path: " pathcheck # Несколько переменных (разделение по IFS) read -p "Enter first and last name: " first last # Чтение в массив read -a myarray # Без переменной — результат в $REPLY read echo "$REPLY" # Чтение строки из пайпа (не интерактивно) echo "hello world" | read -r line; echo "$line"

Флаги и опции

ФлагОписание
-p "prompt"Вывести строку prompt перед ожиданием ввода (без перевода строки). Самый распространённый флаг: read -p "Enter path: " var
-rRaw mode: не интерпретировать символ \ как экранирующий. Рекомендуется всегда использовать при чтении путей и файловых данных
-sSilent mode: не отображать вводимые символы (для паролей и секретов)
-a arrayЧитать слова (разделённые IFS) в индексированный массив, а не в одну строку
-n NВернуть управление после прочтения N символов, не ожидая нажатия Enter
-N NЧитать ровно N символов, игнорируя разделители IFS (в отличие от -n)
-t NТаймаут: вернуть ненулевой код если за N секунд ввода не поступило
-d delimИспользовать символ delim вместо перевода строки как признак конца ввода
-i textИспользовать text как начальное значение (работает только при readline)
-u fdЧитать из дескриптора файла fd, а не из stdin
-eИспользовать readline для ввода (история, автодополнение Tab)

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

Из урока 27: pinger.sh

#!/usr/bin/env bash
# pinger.sh — запрос адреса у пользователя

read -p "Введите адрес для пинга: " address
count=4

echo "Pinging $address..."
ping -c "$count" "$address" | awk -F'/' '/^rtt/ { print "Avg RTT: " $5 " ms" }'

Из урока 27: md5_control.sh

#!/usr/bin/env bash
# Запрос пути к директории для контроля

read -p "Enter path for control: " pathcheck

if [ ! -d "$pathcheck" ]; then
  echo "Error: directory not found: $pathcheck"
  exit 1
fi

for var in $(ls "$pathcheck"); do
  md5sum "$pathcheck/$var" >> "$pathcheck"-md5sum.txt
done

Из урока 30: copy_by_ext.sh

#!/usr/bin/env bash
# Скрипт копирования файлов по расширению

read -p "Enter source directory: " source_directory
read -p "Enter target directory: " target_directory
read -p "Enter file extension (e.g. txt): " file_extension

[ ! -d "$source_directory" ] && { echo "Source not found"; exit 1; }
[ ! -d "$target_directory" ] && { echo "Target not found"; exit 1; }

find "$source_directory" -maxdepth 1 -type f \
  -name "*.$file_extension" -exec cp {} "$target_directory" \;

Дополнительные паттерны

# Ввод пароля без отображения
read -s -p "Password: " password
echo  # перевод строки после ввода

# Чтение с таймаутом (5 секунд)
if read -t 5 -p "Press Enter to continue... " _; then
  echo "Continuing..."
else
  echo "Timeout — auto-continuing"
fi

# Подтверждение (y/n)
read -n 1 -p "Are you sure? [y/N]: " confirm
echo
[[ "$confirm" =~ ^[Yy]$ ]] && echo "Confirmed" || echo "Cancelled"

Советы и предупреждения

Совет: всегда добавляйте -r при чтении путей
Без флага -r обратный слеш в конце строки воспринимается как продолжение ввода на следующей строке. Для путей и данных файловой системы рекомендуется: read -r -p "Enter path: " pathcheck. Большинство скриптов из курса используют read -p без -r — это упрощение, допустимое для учебных целей.
Совет: read в пайпе — отдельный subshell
В bash код echo "hello" | read var не работает как ожидается: read выполняется в subshell пайпа, переменная var исчезает по окончании пайпа. Используйте process substitution: read var < <(echo "hello") или here-string: read var <<< "hello".
Внимание: read — bash built-in, не утилита
Команда which read и type read дают разные результаты: type read покажет read is a shell builtin. Это значит, что read нельзя вызвать из #!/bin/sh-скриптов с расчётом на поведение bash: в dash (sh по умолчанию в Ubuntu) флаг -p может не поддерживаться. Всегда используйте shebang #!/usr/bin/env bash в скриптах, которые используют read -p.