junior
Как работает перенаправление ввода/вывода?
Перенаправление ввода/вывода — это механизм, позволяющий изменить стандартные источники и приёмники данных для процесса.
Аналогия
Представьте трубопровод на заводе. По умолчанию вода (данные) приходит из крана (клавиатура), а уходит в раковину (экран). Перенаправление позволяет подключить другой источник (файл вместо клавиатуры) или другой приёмник (файл вместо экрана), не меняя сам механизм обработки.
Три стандартных потока
В Unix каждый процесс имеет три стандартных потока:
- stdin (0) — стандартный ввод (обычно клавиатура)
- stdout (1) — стандартный вывод (обычно терминал)
- stderr (2) — стандартный поток ошибок (обычно терминал)
Перенаправление stdout
Пример
echo "Hello" > file.txt # Записать в файл (перезаписать)
echo "World" >> file.txt # Дописать в конец файла
ls /nonexistent > output.txt # Ошибки НЕ попадут в файл — пойдут в терминал
Перенаправление stderr
Пример
ls /nonexistent 2> errors.txt # Ошибки в файл
ls /nonexistent 2>> errors.txt # Дописать ошибки в файл
Перенаправление stdout и stderr вместе
Пример
# stdout и stderr в один файл
command > output.txt 2>&1 # Классический синтаксис
command &> output.txt # Сокращённый синтаксис (bash)
# stdout и stderr в разные файлы
command > stdout.txt 2> stderr.txt
# Дописать оба потока в файл
command >> output.txt 2>&1
Перенаправление stdin
Пример
sort < unsorted.txt # Подать файл на вход sort
mysql -u root mydb < dump.sql # Подать SQL-дамп на вход mysql
/dev/null — подавление вывода
Пример
# Подавить весь вывод
command > /dev/null 2>&1
# Подавить только ошибки
command 2> /dev/null
# Подавить только stdout, оставив ошибки
command > /dev/null
Here Document и Here String
Пример
# Here Document — многострочный ввод
cat << EOF
Многострочный
текст
с переменной $HOME
EOF
# Без подстановки переменных
cat << 'EOF'
$HOME не будет раскрыта
EOF
# Here String — подать строку на stdin
grep "pattern" <<< "строка для поиска"
Порядок перенаправлений имеет значение
Это ключевой момент, на котором часто ошибаются:
| Запись | Что произойдёт |
|---|---|
command > file 2>&1 |
stderr направляется туда, куда уже указывает stdout (в file). Оба потока в файле. |
command 2>&1 > file |
stderr направляется туда, куда сейчас указывает stdout (в терминал), затем stdout перенаправляется в file. Ошибки — в терминале, stdout — в файле. |
На собеседовании: интервьюер почти наверняка спросит про разницу между
>и>>, про2>&1и порядок перенаправлений. Частая ошибка — писатьcommand 2>&1 > fileвместоcommand > file 2>&1, ожидая, что оба потока попадут в файл.