Редиректы в файлы и дозапись

Сохраняем вывод команд в файлы и читаем из них.

Редирект — это перенаправление потока команды в файл или из файла вместо терминала.

Запись и дозапись

Оператор > отправляет stdout в файл, перезаписывая его. Оператор >> дописывает в конец.

echo "первая строка" > log.txt
echo "вторая строка" >> log.txt
cat log.txt

Вывод:

первая строка
вторая строка

Если бы во второй команде стоял один >, файл бы перезаписался и осталась только вторая строка. Один > всегда стирает прежнее содержимое — будьте осторожны.

Чтение из файла

Оператор < подаёт содержимое файла в stdin команды.

wc -l < log.txt

Вывод:

2

Здесь wc -l читает не имя файла, а его содержимое из stdin и считает строки.

Объединение вывода и ошибок

Чтобы собрать в один файл и результат, и ошибки, объединяют потоки записью 2>&1 — «направь поток 2 туда же, куда идёт поток 1».

./deploy.sh > deploy.log 2>&1

Порядок важен: сначала > deploy.log переводит stdout в файл, затем 2>&1 приклеивает stderr к тому же месту. В современных Bash есть короткая форма &> deploy.log, делающая то же самое.

ОператорДействие
>stdout в файл, перезапись
>>stdout в файл, дозапись
<stdin из файла
2>&1stderr туда же, куда stdout

Как работает под капотом

Редиректы Bash настраивает до запуска программы, слева направо. Когда вы пишете > file 2>&1, сначала дескриптор 1 переводится на файл, затем дескриптор 2 копирует туда, куда сейчас указывает 1, — то есть на тот же файл. Если поменять порядок (2>&1 > file), результат будет другим: stderr приклеится к терминалу ещё до того, как stdout уйдёт в файл.

Частые ошибки

  • Один > вместо >>. Случайно стирает накопленный лог. Для логов почти всегда нужна дозапись.
  • Неверный порядок 2>&1. Ставьте его ПОСЛЕ редиректа stdout, иначе ошибки не попадут в файл.
  • cmd > file и cmd < file одновременно с одним файлом. Чтение и перезапись одного файла в одной команде портит данные.

Итог

  • > перезаписывает файл, >> дописывает в конец.
  • < подаёт файл в stdin команды.
  • > file 2>&1 (или &> file) собирает и вывод, и ошибки в один файл; порядок важен.
Проверьте себя
1. Чем отличается > от >> при записи в файл?
AНичем
B> перезаписывает файл, >> дописывает в конец
C>> перезаписывает, > дописывает
D> работает только с текстом
2. Что делает запись cmd > out.txt 2>&1?
AПишет только ошибки
BПишет и stdout, и stderr в out.txt
CЧитает из out.txt
DУдаляет out.txt
3. Почему важен порядок в > file 2>&1?
AПорядок не важен
B2>&1 копирует текущее направление stdout, поэтому его ставят после редиректа stdout
C2>&1 всегда должен быть первым
DBash сортирует редиректы сам