Я боюсь, что ваше понимание полностью назад. :)
Думайте о «стандартном входе», «стандартном выходе» и «стандартной ошибке» с точки зрения программы , а не с точки зрения ядра.
Когда программе нужно распечатать вывод, она обычно печатает в «стандартный вывод». Программа обычно печатает вывод на стандартный вывод printf
, который печатает ТОЛЬКО на стандартный вывод.
Когда программе необходимо напечатать информацию об ошибке (не обязательно исключения, это конструкция языка программирования, наложенная на гораздо более высокий уровень), она обычно печатает до «стандартной ошибки». Обычно это делается с помощью fprintf
, который принимает файловый поток для использования при печати. Файловым потоком может быть любой файл, открытый для записи: стандартный вывод, стандартная ошибка или любой другой файл, открытый с помощью fopen
или fdopen
.
«Стандартный вход» используется, когда файл должен прочитать ввод, используя fread
или fgets
, или getchar
.
Любой из этих файлов может быть легко перенаправлен из оболочки, например так:
cat /etc/passwd > /tmp/out # redirect cat's standard out to /tmp/foo
cat /nonexistant 2> /tmp/err # redirect cat's standard error to /tmp/error
cat < /etc/passwd # redirect cat's standard input to /etc/passwd
Или вся энчилада
cat < /etc/passwd > /tmp/out 2> /tmp/err
Есть два важных предостережения: во-первых, «стандартный вход», «стандартный выход» и «стандартная ошибка» - это просто соглашение. Это очень строгое соглашение, но это всего лишь соглашение о том, что очень приятно иметь возможность запускать программы, подобные этой: grep echo /etc/services | awk '{print $2;}' | sort
и иметь стандартные выходные данные каждой программы, подключенные к стандартному входу следующей программы в конвейере.
Во-вторых, я дал стандартные функции ISO C для работы с файловыми потоками ( FILE *
объектами) - на уровне ядра это все файловые дескрипторы ( int
ссылки на таблицу файлов) и много операций более низкого уровня, таких как read
и write
, которые не сделайте счастливую буферизацию функций ISO C. Я решил сделать это простым и использовать более простые функции, но я все же подумал, что вы должны знать альтернативы. :)