Введение
Этот учебник проведет вас через работу со стандартными потоками Linux, уделяя особое внимание пониманию и управлению потоком стандартной ошибки (stderr). Вы узнаете, как использовать мощную команду tee для захвата и обработки вывода stderr, что является ценным навыком для обработки ошибок и ведения журналов в системах Linux.
Понимание стандартных потоков Linux
Linux использует три основных потока для обработки операций ввода и вывода. Эти потоки формируют основу того, как программы взаимодействуют в среде Linux.
Что такое стандартные потоки?
Откройте терминал в вашей среде Linux. Мы рассмотрим концепцию стандартных потоков на практических примерах.
Стандартные потоки - это каналы связи, которые соединяют программы с их окружением. Linux имеет три стандартных потока:
- Стандартный ввод (stdin) - файловый дескриптор 0
- Стандартный вывод (stdout) - файловый дескриптор 1
- Стандартная ошибка (stderr) - файловый дескриптор 2
Давайте посмотрим, как эти потоки работают на практике, используя простые команды.
Демонстрация стандартного ввода (stdin)
Стандартный ввод - это способ, которым программы получают данные, обычно с клавиатуры.
Введите следующую команду в вашем терминале:
cat
Теперь введите любой текст и нажмите Enter. Команда cat считывает данные из stdin и выводит их в stdout. Введите еще несколько строк текста.
Чтобы выйти из команды cat, нажмите Ctrl+D (что сигнализирует о конце файла).
Демонстрация стандартного вывода (stdout)
Стандартный вывод - это место, куда программы отправляют свой обычный вывод.
Выполните эту команду:
echo "This message goes to standard output"
Вы должны увидеть:
This message goes to standard output
Команда echo отправляет текст в stdout, который отображается в вашем терминале.
Демонстрация стандартной ошибки (stderr)
Стандартная ошибка - это место, куда программы отправляют сообщения об ошибках и предупреждения.
Выполните эту команду, чтобы сгенерировать ошибку:
ls /nonexistent_directory
Вы должны увидеть сообщение об ошибке, похожее на:
ls: cannot access '/nonexistent_directory': No such file or directory
Это сообщение об ошибке отправляется в stderr, но оно отображается в вашем терминале так же, как и stdout.
Различие между stdout и stderr
Чтобы увидеть разницу между stdout и stderr, давайте перенаправим их отдельно:
ls /home /nonexistent_directory > output.txt 2> error.txt
Теперь изучите содержимое каждого файла:
cat output.txt
cat error.txt
Вы должны увидеть, что output.txt содержит список содержимого каталога /home, а error.txt содержит сообщение об ошибке для несуществующего каталога.
Понимание того, как работают эти потоки, имеет решающее значение для управления вводом и выводом программ в Linux.
Знакомство с командой tee
Теперь, когда вы понимаете стандартные потоки, давайте узнаем о команде tee, которая предлагает мощный способ управления этими потоками.
Что такое команда tee?
Команда tee в Linux принимает ввод и отправляет его как в стандартный вывод, так и в один или несколько файлов одновременно. Она названа в честь Т-образного разветвителя, используемого в сантехнике, который направляет воду в двух направлениях.
Давайте рассмотрим, как работает tee, на простом примере:
echo "Hello, tee command" | tee hello.txt
Вы должны увидеть:
Hello, tee command
Этот текст отображается в вашем терминале, а также сохраняется в файле hello.txt. Убедитесь в этом, проверив файл:
cat hello.txt
Объединение tee со стандартным выводом
Давайте посмотрим, как мы можем использовать tee с выводом программы:
ls -la ~ | tee home_contents.txt
Эта команда выводит список содержимого вашей домашней директории, отображает его на экране и сохраняет в файле home_contents.txt.
Базовая обработка ошибок с помощью tee
По умолчанию tee захватывает только стандартный вывод. Чтобы захватить также стандартную ошибку, нам нужно сначала перенаправить stderr в stdout.
Попробуйте этот пример:
ls /home /nonexistent_directory 2>&1 | tee mixed_output.txt
Часть 2>&1 перенаправляет stderr (файловый дескриптор 2) в stdout (файловый дескриптор 1), объединяя оба потока. Затем команда tee захватывает этот объединенный вывод.
Изучите содержимое файла:
cat mixed_output.txt
Вы должны увидеть как список каталогов, так и сообщение об ошибке в файле.
Добавление вывода вместо перезаписи
Если вы хотите добавить данные в файл, а не перезаписывать его, используйте опцию -a:
echo "First line" | tee log.txt
echo "Second line" | tee -a log.txt
Проверьте содержимое:
cat log.txt
Вы должны увидеть обе строки в файле, так как вторая команда добавила данные в файл, а не перезаписала его.
Расширенная обработка ошибок с помощью tee
Теперь, когда вы понимаете основы tee, давайте рассмотрим более продвинутые способы использования для обработки ошибок и ведения журналов.
Разделение стандартного вывода и стандартной ошибки
Иногда вам нужно захватить stdout и stderr отдельно, при этом отображая оба в терминале. Давайте создадим скрипт, который генерирует оба типа вывода:
nano test_script.sh
Добавьте следующее содержимое в скрипт:
#!/bin/bash
echo "This is standard output"
echo "This is standard error" >&2
ls /home
ls /nonexistent_directory
Сохраните файл (нажмите Ctrl+O, затем Enter) и выйдите (нажмите Ctrl+X).
Сделайте скрипт исполняемым:
chmod +x test_script.sh
Теперь запустите скрипт с отдельным захватом stdout и stderr:
./test_script.sh > >(tee stdout.log) 2> >(tee stderr.log >&2)
Эта сложная команда:
- Запускает ваш скрипт
- Перенаправляет stdout в
tee stdout.log, который отображает его на экране и сохраняет в файл - Перенаправляет stderr в
tee stderr.log >&2, который отображает его на экране и сохраняет в файл
Изучите результаты:
cat stdout.log
cat stderr.log
Вы должны увидеть обычный вывод в stdout.log и сообщения об ошибках в stderr.log.
Создание полного журнала ошибок
Для комплексного ведения журнала вам может потребоваться:
- Отправлять обычный вывод на экран
- Отправлять ошибки как на экран, так и в файл журнала
- Добавлять метки времени к ошибкам для упрощения отслеживания
Давайте создадим скрипт для демонстрации этого:
nano logging_script.sh
Добавьте следующее содержимое:
#!/bin/bash
## Function to generate a timestamp
timestamp() {
date +"%Y-%m-%d %H:%M:%S"
}
## Echo with timestamp to stderr
echo_error() {
echo "$(timestamp) - ERROR: $1" >&2
}
## Normal output
echo "Starting the script"
## Error output
echo_error "Something went wrong"
## More normal output
echo "Script continuing despite the error"
## Another error
echo_error "Another issue occurred"
## Final output
echo "Script completed"
Сохраните и сделайте скрипт исполняемым:
chmod +x logging_script.sh
Теперь запустите его с ведением журнала ошибок:
./logging_script.sh 2> >(tee -a error_log.txt >&2)
Это:
- Отобразит весь вывод (как stdout, так и stderr) на экране
- Дополнительно захватит stderr в файл
error_log.txt
Проверьте журнал ошибок:
cat error_log.txt
Вы должны увидеть только сообщения об ошибках с метками времени, что упрощает их отслеживание.
Реальное применение: команда с отображением прогресса и обработкой ошибок
Давайте создадим практический пример, который загружает файл, отображая прогресс на экране, при этом регистрируя ошибки:
wget https://example.com/nonexistent_file.txt 2> >(tee -a download_errors.log >&2)
Эта команда:
- Пытается загрузить файл, которого не существует
- Отображает весь вывод на экране, включая прогресс и ошибки
- Дополнительно регистрирует любые ошибки в
download_errors.log
Проверьте журнал ошибок:
cat download_errors.log
Журнал ошибок содержит только сообщения об ошибках из неудачной попытки загрузки.
Эти методы позволяют вам создавать сложные системы обработки ошибок и ведения журналов, используя стандартные команды Linux.
Резюме
В этом руководстве вы изучили основные методы управления стандартными потоками в Linux, с акцентом на обработку ошибок с использованием команды tee. Теперь вы понимаете:
- Три стандартных потока в Linux: stdin, stdout и stderr
- Как использовать команду
teeдля захвата вывода, отображая его на экране - Как перенаправить stderr в stdout и захватить оба потока с помощью
tee - Расширенные методы разделения и ведения журналов различных потоков вывода
- Как реализовать практическое ведение журнала ошибок в реальных сценариях
Эти навыки ценны для создания надежных скриптов, устранения неполадок в приложениях и ведения подробных журналов в средах Linux. Способность эффективно управлять стандартным выводом ошибок поможет вам разрабатывать более профессиональные и удобные в обслуживании приложения Linux.



