read
Чтение строки из стандартного ввода в переменную — встроенная команда bash (bash built-in)
Описание
read — встроенная команда оболочки Bash (bash built-in), которая читает одну строку из стандартного ввода (stdin) и сохраняет её в переменную. В отличие от внешних утилит (ls, grep, tar), read реализована непосредственно внутри bash и не имеет отдельного исполняемого файла в файловой системе.
Главное применение — интерактивный ввод в bash-скриптах. Флаг -p "Prompt: " выводит приглашение пользователю без перевода строки: скрипт выдаёт подсказку и ждёт ввода. В уроках 27 и 30 read -p используется для запроса пути, адреса или имени файла перед обработкой.
По умолчанию read сохраняет прочитанную строку в переменную REPLY (если переменная не указана). Разделителем слов служит содержимое переменной IFS (по умолчанию: пробел, табуляция, перевод строки).
Синтаксис
Флаги и опции
| Флаг | Описание |
|---|---|
-p "prompt" | Вывести строку prompt перед ожиданием ввода (без перевода строки). Самый распространённый флаг: read -p "Enter path: " var |
-r | Raw mode: не интерпретировать символ \ как экранирующий. Рекомендуется всегда использовать при чтении путей и файловых данных |
-s | Silent 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 обратный слеш в конце строки воспринимается как продолжение ввода на следующей строке. Для путей и данных файловой системы рекомендуется: read -r -p "Enter path: " pathcheck. Большинство скриптов из курса используют read -p без -r — это упрощение, допустимое для учебных целей.
В bash код
echo "hello" | read var не работает как ожидается: read выполняется в subshell пайпа, переменная var исчезает по окончании пайпа. Используйте process substitution: read var < <(echo "hello") или here-string: read var <<< "hello".
Команда
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.