Запутался в stdin, stdout и stderr?
Я довольно запутался с целью этих трех файлов. Если мое понимание верно,stdin
- это файл, в который программа записывает свои запросы на выполнение задачи в процессе,stdout
- это файл, в который ядро записывает свои выходные данные и процесс, запрашивающий у него доступ к информации, и stderr
это файл, в который вошли все исключения. При открытии этих файлов, чтобы проверить, действительно ли они происходят, я не нашел ничего, кажется, предложить Итак!
то, что я хотел бы знать, что именно является целью этих файлов, абсолютно тупой ответ с очень небольшим техническим жаргоном!
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. Я решил сохранить его простым и использовать более простые функции, но я думал, что все то же самое вы должны знать альтернативы. :)
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 - стандартный файл ошибокно только это хорошо работало для/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() создает определенные описательные данные для потока и возвращает указатель для обозначения потока во всех последующих сделок. Обычно есть три открытых потока с постоянными указателями, объявленными в заголовке и связанными со стандартными открытыми файлами. При запуске программы три потока предопределены и не должны быть открыты явно: стандартный ввод (для чтение обычного входа), стандартный выход (для записи обычного выхода) и стандартная ошибка (для записи диагностического выхода). При открытии стандартный поток ошибок не полностью буферизуется; стандартный входной и стандартный выходной потоки полностью буферизуются тогда и только тогда, когда поток может быть определен как не относящийся к интерактивному устройству