Одним из различий между stdout
и stderr
является уровень буферизации. В §7.21.3 файлах *7 стандарт C11 гласит:
При запуске программы три текстовых потока предопределены и не требуют явного открытия - стандартный ввод (для чтение обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностики c вывода). При первоначальном открытии стандартный поток ошибок не полностью буферизован; стандартные входные и стандартные выходные потоки полностью буферизуются в том и только в том случае, если можно определить, что поток не относится к интерактивному устройству.
Как правило, это означает, что стандартный вывод является линейной буферизацией (поэтому данные сбрасывается при печати новой строки или при заполнении буфера), тогда как стандартной ошибкой является либо буферизация строки, либо небуферизация. Разумеется, эти характеристики можно изменить.
Целью стандартного потока ошибок является отделение сообщений об ошибках от обычного вывода. Это важно в таких контекстах, как сценарии оболочки, где стандартный вывод может быть отправлен в канал или в файл. Это перенаправление оставляет стандартную ошибку по-прежнему в другом месте - обычно это терминал. Вы также можете захватить стандартный вывод отдельно от стандартной ошибки, по крайней мере, если оболочка достаточно мощная.
program > file
program | filter
program 2> error.log | filter
program > file 2> error.log
program 2> error.log
Первые два оставляют сообщения об ошибках видимыми на терминале. Последние три фиксируют сообщения об ошибках в файле error.log
- отправка стандартного вывода в программу filter
, file
или в окно терминала соответственно.
Путем отделения сообщений об ошибках от стандартного выводим, что программы по конвейеру (filter
в моем примере) не должны интерпретировать сообщения об ошибках от program
, что делает их намного, намного проще.