Я довольно запутался с целью этих трех файлов. Если я правильно понимаю, stdin
это файл, в который программа записывает свои запросы на выполнение задачи в процессе, stdout
это файл, в который ядро записывает свои выходные данные, и процесс, запрашивающий его, получает доступ к информации и stderr
является ли этот файл в которые все исключения введены. Открыв эти файлы, чтобы проверить, действительно ли они происходят, я не нашел ничего, что могло бы предложить это!
То, что я хотел бы знать, какова цель этих файлов, абсолютно тупой ответ с очень небольшим техническим жаргоном!
Ответы:
Стандартный ввод - это дескриптор файла, который ваш процесс читает, чтобы получить информацию от вас.
Стандартный вывод - ваш процесс записывает обычную информацию в этот дескриптор файла.
Стандартная ошибка - ваш процесс записывает информацию об ошибке в этот дескриптор файла.
Это настолько глупо, насколько я могу это сделать :-)
Конечно, это в основном по соглашению. Ничто не мешает вам записать информацию об ошибках в стандартный вывод, если хотите. Вы даже можете полностью закрыть три файловых дескриптора и открыть свои собственные файлы для ввода / вывода.
Когда ваш процесс запускается, у него уже должны быть открыты эти маркеры, и он может просто читать и / или записывать их.
По умолчанию они, вероятно, подключены к вашему оконечному устройству (например,
/dev/tty
), но оболочки позволят вам установить соединения между этими дескрипторами и конкретными файлами и / или устройствами (или даже конвейерами к другим процессам) до запуска вашего процесса (некоторые из возможные манипуляции довольно умны).Примером является:
который будет:
my_prog
.inputfile
как ваш стандартный ввод (дескриптор файла 0).errorfile
как стандартную ошибку (дескриптор файла 2).grep
.my_prog
к стандартному входуgrep
.Re ваш комментарий:
Это потому что они не нормальные файлы. В то время как UNIX представляет все как файл в файловой системе где-то, это не делает это на самых низких уровнях. Большинство файлов в
/dev
иерархии являются символьными или блочными устройствами, фактически драйвером устройства. У них нет размера, но у них есть старший и младший номер устройства.Когда вы открываете их, вы подключаетесь к драйверу устройства, а не к физическому файлу, и драйвер устройства достаточно умен, чтобы знать, что отдельные процессы должны обрабатываться отдельно.
То же самое верно для
/proc
файловой системы Linux . Это не настоящие файлы, это просто строго контролируемые шлюзы с информацией о ядре.источник
xyz >xyz.out
запишет ваш стандартный вывод в физический файл, который может быть прочитан другими процессами.xyz | grep something
подключит стандартныйxyz
вывод к стандартномуgrep
вводу напрямую. Если вам нужен беспрепятственный доступ к процессу, который вы не контролируете таким образом, вам нужно изучить что-то вроде/proc
или написать код, чтобы отфильтровать вывод, каким-то образом подключившись к ядру. Могут быть и другие решения, но все они, вероятно, так же опасны, как и другие :-)/dev/stdin
это символическая ссылка/proc/self/fd/0
на первый дескриптор файла, который открыта в настоящий момент запущенной программой. Таким образом, то, на что указывает,/dev/stdin
будет меняться от программы к программе, потому что/proc/self/
всегда указывает на «запущенную программу». (Какая бы программа ни выполнялаopen
вызов.)/dev/stdin
И друзей отправили туда, чтобы сделать сценарии оболочки setuid более безопасными, и позволить передавать имя файла/dev/stdin
программам, которые работают только с файлами, но вы хотите управлять более интерактивно. (Когда-нибудь это будет полезная уловка для вас. :)Было бы правильнее сказать , что
stdin
,stdout
иstderr
являются «I / O потоков» , а не файлы. Как вы заметили, эти сущности не живут в файловой системе. Но философия Unix, что касается ввода / вывода, заключается в том, что «все это файл». На практике, это действительно означает , что вы можете использовать одни и те же функции библиотеки и интерфейсы (printf
,scanf
,read
,write
,select
и т.д.) , не заботясь о том , подключен ли поток ввода / вывода с клавиатуры, дисковый файл, сокет, труба, или какая-то другая абстракция ввода / вывода.Большинство программ должны читать ввод, вывод записи и ошибки журнала, так
stdin
,stdout
иstderr
предопределены для вас, для удобства программирования. Это всего лишь соглашение и не применяется операционной системой.источник
В качестве дополнения к ответам, приведенным выше, ниже приводится сводная информация о перенаправлениях:
РЕДАКТИРОВАТЬ: эта графика не совсем правильно, но я не уверен, почему ...
На рисунке написано, что 2> & 1 имеет тот же эффект, что и &> однако
источник
Я боюсь, что ваше понимание полностью назад. :)
Думайте о «стандартном входе», «стандартном выходе» и «стандартной ошибке» с точки зрения программы , а не с точки зрения ядра.
Когда программе нужно распечатать вывод, она обычно печатает в «стандартный вывод». Программа обычно печатает вывод на стандартный вывод
printf
, который печатает ТОЛЬКО на стандартный вывод.Когда программе необходимо напечатать информацию об ошибке (не обязательно исключения, это конструкция языка программирования, наложенная на гораздо более высокий уровень), она обычно печатает до «стандартной ошибки». Обычно это делается с помощью
fprintf
, который принимает файловый поток для использования при печати. Файловым потоком может быть любой файл, открытый для записи: стандартный вывод, стандартная ошибка или любой другой файл, открытый с помощьюfopen
илиfdopen
.«Стандартный вход» используется, когда файл должен прочитать ввод, используя
fread
илиfgets
, илиgetchar
.Любой из этих файлов может быть легко перенаправлен из оболочки, например так:
Или вся энчилада
Есть два важных предостережения: во-первых, «стандартный вход», «стандартный выход» и «стандартная ошибка» - это просто соглашение. Это очень строгое соглашение, но это всего лишь соглашение о том, что очень приятно иметь возможность запускать программы, подобные этой:
grep echo /etc/services | awk '{print $2;}' | sort
и иметь стандартные выходные данные каждой программы, подключенные к стандартному входу следующей программы в конвейере.Во-вторых, я дал стандартные функции ISO C для работы с файловыми потоками (
FILE *
объектами) - на уровне ядра это все файловые дескрипторы (int
ссылки на таблицу файлов) и много операций более низкого уровня, таких какread
иwrite
, которые не сделайте счастливую буферизацию функций ISO C. Я решил сделать это простым и использовать более простые функции, но я все же подумал, что вы должны знать альтернативы. :)источник
STDIN
Читает ввод через консоль (например, ввод с клавиатуры). Используется в C с scanf
стандартный вывод
Производит вывод на консоль. Используется в C с printf
STDERR
Выводит ошибку на консоль. Используется в C с fprintf
Перенаправление
Источник для stdin может быть перенаправлен. Например, вместо ввода с клавиатуры это может быть файл (
echo < file.txt
) или другая программа (ps | grep <userid>
).Направления для stdout, stderr также могут быть перенаправлены. Например, stdout может быть перенаправлен в файл:
ls . > ls-output.txt
в этом случае вывод записывается в файлls-output.txt
. Stderr может быть перенаправлен с2>
.источник
Я думаю, что люди, говорящие,
stderr
должны использоваться только для сообщений об ошибках, вводят в заблуждение.Его также следует использовать для информативных сообщений, предназначенных для пользователя, выполняющего команду, а не для любых потенциальных нижестоящих потребителей данных (т. Е. Если вы запускаете конвейер оболочки, объединяющий несколько команд, вам не нужны информативные сообщения, такие как «получение элемента 30 42424 ",
stdout
потому что они могут запутать потребителя, но вы все равно хотите, чтобы пользователь их увидел.Смотрите это для исторического обоснования:
источник
Использование 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 для печати ошибок или сообщений журнала.
Каждая программа Unix имеет каждый из этих потоков.
источник
stderr не будет выполнять буферизацию IO Cache, поэтому, если нашему приложению нужно вывести критическую информацию о сообщении (некоторые ошибки, исключения) на консоль или в файл, используйте ее, где, как и stdout, для печати общей информации журнала, так как она использует буферизацию IO Cache, есть вероятность, что перед записью наших сообщений в файл приложение может закрыться, оставив комплекс отладки
источник
Файл со связанной буферизацией называется потоком и объявляется указателем на определенный тип FILE. Функция fopen () создает определенные описательные данные для потока и возвращает указатель для обозначения потока во всех дальнейших транзакциях. Обычно есть три открытых потока с постоянными указателями, объявленными в заголовке и связанными со стандартными открытыми файлами. При запуске программы три потока предопределены и не требуют явного открытия: стандартный ввод (для чтения обычного ввода), стандартный вывод (для записи обычного вывода) и стандартная ошибка (для записи диагностического вывода). При открытии стандартный поток ошибок не полностью буферизуется; стандартные входные и стандартные выходные потоки полностью буферизуются тогда и только тогда, когда можно определить, что поток не относится к интерактивному устройству
https://www.mkssoftware.com/docs/man5/stdio.5.asp
источник