Gymterview
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, ожидая, что оба потока попадут в файл.