При перенаправлении команд command1 | command2 перенаправляется только stdout. Как сделать так, чтобы stderr тоже перенаправлялся?devops-28

При использовании конвейера (command1 | command2) по умолчанию перенаправляется только стандартный вывод (stdout), а стандартный поток ошибок (stderr) продолжает выводиться в терминал. Вот как можно перенаправить оба потока:

Основные способы

1. Перенаправление stderr в stdout перед конвейером

command1 2>&1 | command2

Объяснение:

  • 2>&1 перенаправляет дескриптор 2 (stderr) в дескриптор 1 (stdout)
  • После этого оба потока попадают в конвейер

2. Перенаправление в разные места

command1 2> error.log | command2 > output.log

Объяснение:

  • stderr записывается в файл error.log
  • stdout передается в command2, а его вывод сохраняется в output.log

3. Использование process substitution

command1 > >(command2) 2>&1

Объяснение:

  • >(command2) создает временный файловый дескриптор для command2
  • 2>&1 объединяет потоки

Особые случаи

Если нужно сохранить порядок вывода

{ command1 2>&1 1>&3 | command2; } 3>&1

Объяснение:

  1. Создается дополнительный дескриптор (3) для оригинального stdout
  2. stderr перенаправляется в текущий stdout (который ведет в конвейер)
  3. Оригинальный stdout сохраняется через дескриптор 3

Для современных версий Bash

command1 |& command2

Объяснение:

  • |& это сокращение для 2>&1 |

Резюмируем

  1. Основной способ: 2>&1 |
  2. Для разделения потоков: использовать разные файлы
  3. В современных Bash можно использовать сокращенную форму |&
  4. Для сложных сценариев могут потребоваться дополнительные дескрипторы

Все методы работают в POSIX-совместимых оболочках, кроме специально отмеченных Bash-специфичных вариантов.