open atlas
↑ К треку
Командная строка CLI · 03 · 02

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

Перенаправление перепрокладывает стандартные потоки до запуска команды: > усекает stdout в файл, >> добавляет в конец, < подаёт файл в stdin, 2> перехватывает stderr, а 2>&1 сливает stderr в stdout. Порядок операторов имеет значение.

CLI Junior ◷ 22 min
Уровень
ОсновыJuniorMiddleSenior

Ты знаешь, что команды пишут в stdout и stderr и читают из stdin. А что, если ты хочешь сохранить вывод в файл вместо того, чтобы смотреть, как он прокручивается? Или подать содержимое файла в команду, как будто ты его напечатал? Это перенаправление — способность оболочки перепрокладывать файловые дескрипторы до того, как команда начнёт выполняться. Это одно из самых полезных действий в оболочке, а синтаксис легко запоминается, если увидеть закономерность.

К концу урока ты сможешь перенаправлять stdout и stderr в файлы, добавлять вместо перезаписи, подавать файлы в stdin и — что критически важно — понять, почему 2>&1 должен идти после >, а не перед ним.

Цель

После этого урока ты сможешь использовать > для усечения stdout в файл, >> для добавления, < для подачи файла в stdin, 2> для перехвата stderr и 2>&1 для слияния stderr в stdout. Ты понимаешь правило порядка при комбинированных перенаправлениях.

1

> перенаправляет stdout в файл, предварительно усекая его. Оболочка открывает целевой файл (создавая его при необходимости, усекая до нуля байт если он существует) и заменяет fd 1 этим файлом перед выполнением команды. Команда пишет как обычно — она не знает, что пишет в файл.

ls /etc > /tmp/etc-list.txt

Вывод на экране не появляется. /tmp/etc-list.txt теперь содержит то, что ls /etc вывел бы на экран. Если файл уже имел содержимое, > уничтожает его.

echo "first" > /tmp/demo.txt
echo "second" > /tmp/demo.txt
cat /tmp/demo.txt
second

Второй > стёр “first”. Если ты хочешь сохранить оба, нужен >>.

2

>> добавляет stdout в конец файла. Оболочка открывает файл в режиме добавления — существующее содержимое сохраняется, а новые данные добавляются в конец.

echo "first" > /tmp/demo.txt
echo "second" >> /tmp/demo.txt
cat /tmp/demo.txt
first
second

>> — безопасный способ накапливать вывод от нескольких команд или запусков одного скрипта.

3

< перенаправляет stdin из файла. Оболочка открывает файл и заменяет fd 0 им. Команда читает из fd 0 как обычно — она не знает, что байты приходят из файла, а не с клавиатуры.

wc -l < /etc/passwd

wc -l считает строки. При < /etc/passwd она читает из файла вместо ожидания ввода с клавиатуры. Для большинства инструментов это эквивалентно wc -l /etc/passwd, но некоторые инструменты читают только из stdin (а не из аргумента с именем файла), делая < незаменимым.

4

2> перенаправляет stderr в файл. Так же, как > является сокращением для 1> (перенаправление fd 1), 2> перенаправляет fd 2.

ls /exists /nonexistent 2> /tmp/errors.txt

Обычный вывод из /exists печатается в терминал. Ошибка о /nonexistent тихо уходит в /tmp/errors.txt. Ты можешь проверить ошибки позже, не загромождая экран.

Частое применение: полное отбрасывание ошибок с помощью специального нулевого устройства:

ls /nonexistent 2> /dev/null

/dev/null — устройство, которое тихо отбрасывает всё, что в него записывается. Это Unix-способ сказать «подавить сообщения об ошибках».

5

2>&1 сливает stderr в stdout — но порядок имеет значение. Нотация N>&M означает «сделать fd N указывающим на то же место, на которое сейчас указывает fd M». Таким образом, 2>&1 означает «сделать stderr указывающим на то место, куда сейчас указывает stdout».

ls /exists /nonexistent > /tmp/all.txt 2>&1

Оболочка обрабатывает перенаправления слева направо:

  1. > /tmp/all.txt — fd 1 теперь указывает на /tmp/all.txt.
  2. 2>&1 — fd 2 теперь указывает на то, куда указывает fd 1, то есть на /tmp/all.txt.

Результат: и stdout, и stderr идут в файл.

Классическая ошибка — перепутать порядок:

ls /exists /nonexistent 2>&1 > /tmp/all.txt

Это неправильно. Оболочка читает слева направо:

  1. 2>&1 — fd 2 устанавливается в место, куда сейчас указывает fd 1, то есть на терминал.
  2. > /tmp/all.txt — fd 1 теперь перенаправляется в файл.

Результат: stdout идёт в файл, stderr всё ещё идёт в терминал. Слияние произошло до того, как вступило в силу перенаправление в файл.

Разбор примера

Перехватить весь вывод — stdout и stderr — в единый файл лога.

Скрипт сборки производит и обычный вывод, и сообщения об ошибках. Тебе нужно всё в одном файле для последующей проверки:

make 2>&1 | tee build.log

Или без конвейера, просто в файл:

make > build.log 2>&1

После запуска build.log содержит всё. Чтобы проверить только ошибки:

grep -i error build.log

Теперь попробуй неправильный порядок, чтобы увидеть разницу:

make 2>&1 > build.log

Ошибки из make всё равно печатаются в терминал; в build.log идёт только stdout. Запоминание «сначала перенаправление stdout, затем слияние» предотвращает эту ловушку.

Почему это работает

На macOS/BSD все эти операторы перенаправления работают идентично — это синтаксис оболочки POSIX, а не специфика Linux. /dev/null тоже существует на macOS. Единственное отличие macOS, заслуживающее упоминания: некоторые утилиты macOS ведут себя немного иначе при аргументах с именами файлов против stdin, но сами операторы перенаправления идентичны.

Частая ошибка

Забыть 2>&1, когда нужен по-настоящему полный лог — единственная самая распространённая ошибка перенаправления. Команда может выглядеть успешной в логе, пока тихо выводит ошибки в терминал. Всегда проверяй: «я перехватил оба потока?» Если тебе нужно всё в одном месте: command > file 2>&1. Если нужны раздельные файлы: command > out.txt 2> err.txt.

Проверь себя
Викторина

Ты запускаешь: cmd > out.txt 2>&1. Куда идёт stderr?

Итог

Перенаправление перепрокладывает файловые дескрипторы до запуска команды. > усекает stdout в файл; >> добавляет в конец. < подаёт файл в stdin. 2> перехватывает stderr. 2>&1 копирует fd 2 для указания туда, куда сейчас указывает fd 1 — поэтому он должен идти после любого перенаправления stdout, если ты хочешь, чтобы оба потока шли в одно место. Оболочка обрабатывает все перенаправления слева направо до запуска процесса. Освой правило порядка для 2>&1 — и ты никогда больше не потеряешь вывод ошибок.

Практика

Начни сверху. Задачи идут от простого к сложному: вспомнить факт, применить к случаю, затем senior-уровень. Открой, попробуй, потом открой ответ.

вспомнитьприменитьуглубить0 из 4 завершено

Что-то непонятно?

Задай вопрос по этому уроку. Вопросы анонимны и попадают напрямую автору — урок станет лучше.

хоткеи развернуть
поиск
K
пред. пьеса
k
след. пьеса
j
тиры
t
это меню
?
sources3
expand
  1. 01
  2. 02
  3. 03

Trademarks belong to their respective owners. Editorial reference only.