Gymterview
junior

Что такое перенаправление ввода-вывода и конвейеры (pipes)?

Каждый процесс в Linux имеет три стандартных потока ввода-вывода.

Поток Номер дескриптора Описание
stdin 0 Стандартный ввод (обычно клавиатура)
stdout 1 Стандартный вывод (обычно терминал)
stderr 2 Стандартный вывод ошибок (обычно терминал)

Перенаправление вывода

Пример
ls -la > listing.txt                    # stdout -> файл (перезаписать)
echo "new line" >> listing.txt          # stdout -> файл (дополнить)
java -jar app.jar 2> errors.log         # stderr -> файл
java -jar app.jar > output.log 2>&1     # stdout и stderr -> один файл
java -jar app.jar &> output.log         # Сокращённая форма (bash)
command > /dev/null 2>&1                # Подавить весь вывод

Перенаправление ввода

Пример
psql mydb < schema.sql                  # Ввод из файла

# Here Document
cat << EOF > config.yml
server:
  port: 8080
  host: localhost
EOF

Конвейеры (pipes)

Конвейер | передаёт stdout одной команды на stdin другой:

Пример
# Подсчитать Java-процессы
ps aux | grep java | grep -v grep | wc -l

# Топ-10 больших файлов в /var
du -ah /var | sort -rh | head -10

# Отфильтровать логи
cat application.log | grep "ERROR" | grep "2024-04-01" > errors_today.log

# Уникальные IP-адреса из access.log
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -20

# Мониторинг лога с фильтром
tail -f application.log | grep --line-buffered "ERROR"

tee — вывод в файл и на экран

Пример
ls -la | tee listing.txt                              # Записать и показать
echo "nameserver 8.8.8.8" | sudo tee /etc/resolv.conf # Записать с sudo

xargs — передача stdin как аргументов

Пример
find /tmp -name "*.tmp" | xargs rm                    # Удалить найденные файлы
find /tmp -name "*.tmp" -print0 | xargs -0 rm         # Безопасно (имена с пробелами)
find . -name "*.gz" | xargs -P 4 gunzip               # Параллельное выполнение

На собеседовании: ключевое — понимание |, >, >>, 2>&1. Интервьюер может попросить перенаправить stderr и stdout в разные файлы или объяснить > /dev/null 2>&1. Частая ошибка — путать порядок перенаправлений: 2>&1 > file и > file 2>&1 дают разный результат.