Запутался в stdin, stdout и stderr?


Я довольно запутался с целью этих трех файлов. Если мое понимание верно,stdin - это файл, в который программа записывает свои запросы на выполнение задачи в процессе,stdout - это файл, в который ядро записывает свои выходные данные и процесс, запрашивающий у него доступ к информации, и stderr это файл, в который вошли все исключения. При открытии этих файлов, чтобы проверить, действительно ли они происходят, я не нашел ничего, кажется, предложить Итак!

то, что я хотел бы знать, что именно является целью этих файлов, абсолютно тупой ответ с очень небольшим техническим жаргоном!

10 132

10 ответов:

стандартный ввод - это дескриптор процесс чтения, чтобы получить информацию от вас.

стандартный вывод - ваш процесс записывает нормальную информацию в этот дескриптор файла.

Стандартная ошибка - ваш процесс записывает информацию об ошибке в этот дескриптор файла.

это примерно так же тупо, как я могу это сделать: -)

конечно, это в основном по соглашению. Ничто не мешает вам записать информацию об ошибке в стандартный вывод, если вы хотите. Вы даже можете полностью закрыть три дескриптора файлов и открыть свои собственные файлы для ввода-вывода

когда ваш процесс запускается, он уже должен иметь эти ручки открытыми, и он может просто читать и/или писать в них.

по умолчанию они, вероятно, подключены к вашему оконечному устройству (например,/dev/tty) но оболочки позволят вам настроить соединения между этими маркерами и конкретными файлы и / или устройства (или даже конвейеры для других процессов) до начала вашего процесса (некоторые из возможных манипуляций довольно умны).

пример:

my_prog <inputfile 2>errorfile | grep XYZ

что будет:

  • создать процесс для my_prog.
  • открыть inputfile в качестве стандартного ввода (дескриптор файла 0).
  • открыть errorfile как ваша стандартная ошибка (дескриптор файла 2).
  • создать другое

правильнее было бы сказать, что stdin,stdout и stderr скорее "потоки ввода / вывода" чем файлы. Как вы уже заметили, эти сущности не живут в файловой системе. Но Философия Unix, насколько это касается ввода/вывода, - это "все является файлом". На практике, это действительно означает, что вы можете использовать одни и те же библиотечные функции и интерфейсы (printf, scanf,read,write,select и т. д.) не беспокоясь о том, является ли поток ввода / вывода подключается к клавиатуре, диску файл, сокет, канал или какая-либо другая абстракция ввода-вывода.

большинство программ должны считывать входные данные, записывать выходные данные и регистрировать ошибки, поэтому stdin,stdout, и stderr предопределенные для вас, как удобство программирования. Это всего лишь соглашение, и не применяется операционной системой.

боюсь, что ваше понимание полностью обратное. :)

думаю, "стандарт", "стандарт", и "стандартная ошибка" от программы точки зрения, не с точки зрения ядра.

когда программе нужно напечатать выход, она нормально печатает к "стандарту вне". Программа обычно выводит выходные данные в стандартную форму с помощью printf, который печатает только к стандарту вне.

когда программа должна напечатать информацию об ошибке (не обязательно исключения, это конструкция языка программирования, наложенная на гораздо более высоком уровне), она обычно печатает "стандартную ошибку". Обычно это происходит с fprintf, который принимает поток файлов для использования при печати. Потоком файлов может быть любой файл, открытый для записи: standard out, standard error или любой другой файл, открытый с помощью fopen или fdopen.

"standard in" используется, когда файл должен считывать входные данные, используя 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 ;}' | sort и имеют стандартные выходы каждая программа подключается к стандартному входу следующей программы в конвейере.

во-вторых, я дал стандартные функции ISO C для работы с файловыми потоками (FILE * объекты) -- на уровне ядра, это все файловые дескрипторы (int ссылки на таблицу файлов) и гораздо более низкоуровневые операции, такие как read и write, которые не делают счастливую буферизацию функций ISO C. Я решил сохранить его простым и использовать более простые функции, но я думал, что все то же самое вы должны знать альтернативы. :)

в дополнение к ответам выше, вот сумма о Перенаправлениях: Redirections cheatsheet

stdin

считывает ввод через консоль (например, ввод с клавиатуры). Используется в C с scanf

scanf(<formatstring>,<pointer to storage> ...);

stdout

производит вывод на консоль. Используется в C с printf

printf(<string>, <values to print> ...);

stderr

выводит' error ' на консоль. Используется в C с fprintf

fprintf(stderr, <string>, <values to print> ...);

перенаправление

источник для stdin может быть перенаправлен. Например, вместо того, чтобы исходить из ввода с клавиатуры, он может исходить из файла (echo < file.txt ), или другой программой ( ps | grep <userid>).

направления на стандартный вывод, стандартный вывод можно перенаправить. Например, стандартный вывод можно перенаправить в файл: ls . > ls-output.txt в этом случае результаты записываются в файл ls-output.txt. Stderr можно перенаправить С 2>.

использование ps-aux показывает текущие процессы, все из которых перечислены в /proc/ as /proc/(pid)/, вызывая cat /proc/(pid)/fd/0 он печатает все, что находится в стандартном выходе этого процесса, я думаю. Так что, возможно,

/proc/(pid)/fd/0 - стандартный выходной файл
/proc/(pid)/fd/1 - Стандартный входной файл
/proc/(pid)/fd/2 - стандартный файл ошибок

my terminal window

но только это хорошо работало для/bin / bash других процессов вообще ничего не было в 0, но у многих были ошибки, написанные в 2

Я думаю, что люди говорят, что stderr должен использоваться только для сообщений об ошибках вводит в заблуждение. Он также должен использоваться для информационных сообщений, предназначенных для пользователя, выполняющего команду, а не для каких-либо потенциальных нижестоящих потребителей данных (т. е. если вы запускаете оболочку, соединяющую несколько команд, вы не хотите, чтобы информационные сообщения, такие как "получение элемента 30 из 42424", появлялись на stdout, поскольку они будут путать потребителя, но вы все равно можете захотеть, чтобы пользователь их видел.

посмотреть http://www.jstorimer.com/blogs/workingwithcode/7766119-when-to-use-stderr-instead-of-stdout для исторического обоснования:

" все программы разместили диагностику на стандартном выходе. Это всегда вызывало проблемы, когда вывод перенаправлялся в файл, но становилось невыносимым, когда вывод отправлялся в ничего не подозревающий процесс. Тем не менее, не желая нарушать простоту модели Стандарт-вход-стандарт-выход, люди терпели такое положение дел до V6. Вскоре после этого Деннис Ричи разрубил гордиев узел, введя стандартный файл ошибок. Но этого было недостаточно. С трубопроводами диагностика может исходить из любой из нескольких программ, работающих одновременно. Диагностика необходима, чтобы идентифицировать себя."

stderr не будет выполнять буферизацию кэша ввода-вывода, поэтому, если нашему приложению нужно распечатать критическую информацию о сообщении (некоторые ошибки ,исключения) для консоли или файла ,используйте его, где как использовать stdout для печати общей информации журнала, поскольку он использует буферизацию кэша ввода-вывода, есть вероятность, что перед записью наших сообщений в файл приложение может закрыться, оставив отладочный комплекс

для получения достоверной информации об этих файлах, проверьте справочные страницы, выполните команду на вашем терминале.

$ man stdout 

но для простого ответа, каждый файл для:

stdout в потоке

stdin для ввода потока

stderr для печати ошибок или сообщений журнала.

каждая программа Unix имеет каждый из этих потоков.

файл с соответствующей буферизацией называется потоком и объявляется указателем на определенный тип файла. Функции fopen() создает определенные описательные данные для потока и возвращает указатель для обозначения потока во всех последующих сделок. Обычно есть три открытых потока с постоянными указателями, объявленными в заголовке и связанными со стандартными открытыми файлами. При запуске программы три потока предопределены и не должны быть открыты явно: стандартный ввод (для чтение обычного входа), стандартный выход (для записи обычного выхода) и стандартная ошибка (для записи диагностического выхода). При открытии стандартный поток ошибок не полностью буферизуется; стандартный входной и стандартный выходной потоки полностью буферизуются тогда и только тогда, когда поток может быть определен как не относящийся к интерактивному устройству

https://www.mkssoftware.com/docs/man5/stdio.5.asp