Estou um pouco confuso com o objetivo desses três arquivos. Se meu entendimento estiver correto, stdin
é o arquivo no qual um programa grava suas solicitações para executar uma tarefa no processo, stdout
é o arquivo no qual o kernel grava sua saída e o processo que solicita o acesso às informações e stderr
é o arquivo em em que todas as exceções são inseridas. Ao abrir esses arquivos para verificar se eles realmente ocorrem, não achei nada que sugerisse isso!
O que eu gostaria de saber é qual é exatamente o objetivo desses arquivos, resposta absolutamente estúpida com muito pouco jargão técnico!
Respostas:
Entrada padrão - este é o identificador de arquivo que seu processo lê para obter informações de você.
Saída padrão - seu processo grava informações normais neste identificador de arquivo.
Erro padrão - seu processo grava informações de erro neste identificador de arquivo.
Isso é o mais estúpido que eu consigo :-)
Claro, isso é principalmente por convenção. Não há nada que o impeça de gravar suas informações de erro na saída padrão, se desejar. Você pode até fechar totalmente os três identificadores de arquivo e abrir seus próprios arquivos para E / S.
Quando o processo é iniciado, ele já deve ter esses identificadores abertos e pode apenas ler e / ou gravar neles.
Por padrão, eles provavelmente estão conectados ao seu dispositivo de terminal (por exemplo,
/dev/tty
) , mas os shells permitem que você configure conexões entre esses identificadores e arquivos e / ou dispositivos específicos (ou até pipelines para outros processos) antes do início do processo (alguns dos as manipulações possíveis são bastante inteligentes).Um exemplo sendo:
que irá:
my_prog
.inputfile
como sua entrada padrão (identificador de arquivo 0).errorfile
como seu erro padrão (identificador de arquivo 2).grep
.my_prog
à entrada padrão degrep
.Re seu comentário:
É porque eles não são arquivos normais. Embora o UNIX apresente tudo como um arquivo em um sistema de arquivos em algum lugar, isso não ocorre nos níveis mais baixos. A maioria dos arquivos na
/dev
hierarquia são dispositivos de caracteres ou de bloco, efetivamente um driver de dispositivo. Eles não têm um tamanho, mas têm um número de dispositivo maior e menor.Quando você os abre, você está conectado ao driver de dispositivo, e não a um arquivo físico, e o driver de dispositivo é inteligente o suficiente para saber que processos separados devem ser tratados separadamente.
O mesmo vale para o sistema de
/proc
arquivos Linux . Esses não são arquivos reais, apenas gateways fortemente controlados para obter informações do kernel.fonte
xyz >xyz.out
gravará sua saída padrão em um arquivo físico que pode ser lido por outros processos.xyz | grep something
conectará oxyz
stdout aogrep
stdin mais diretamente. Se você deseja acesso irrestrito a um processo que não controla dessa maneira, precisará procurar algo como/proc
ou escrever um código para filtrar a saída conectando o kernel de alguma forma. Pode haver outras soluções, mas todas elas provavelmente são tão perigosas quanto as outras :-) #/dev/stdin
é um link simbólico para/proc/self/fd/0
- o primeiro descritor de arquivo aberto pelo programa em execução no momento. Portanto, o que é indicado por/dev/stdin
mudará de programa para programa, porque/proc/self/
sempre aponta para o 'programa em execução'. (Qualquer que seja o programa que está fazendo aopen
ligação.)/dev/stdin
E os amigos foram colocados lá para tornar os scripts do shell setuid mais seguros e permitem que você passe o nome do arquivo/dev/stdin
para programas que funcionam apenas com arquivos, mas que você deseja controlar de maneira mais interativa. (Algum dia isso vai ser um truque útil para você conhecer :).Seria mais correto dizer que
stdin
,stdout
estderr
são "fluxos de E / S" em vez de arquivos. Como você notou, essas entidades não vivem no sistema de arquivos. Mas a filosofia do Unix, no que diz respeito à E / S, é "tudo é um arquivo". Na prática, isso realmente significa que você pode usar as mesmas funções de biblioteca e interfaces (printf
,scanf
,read
,write
,select
, etc.) sem se preocupar se o fluxo de I / O é conectado a um teclado, um arquivo em disco, uma tomada, um tubo, ou alguma outra abstração de E / S.A maioria dos programas precisa ler entrada, saída de gravação, e erros de registro, por isso
stdin
,stdout
estderr
são predefinidos para você, como uma conveniência de programação. Esta é apenas uma convenção e não é aplicada pelo sistema operacional.fonte
Como complemento das respostas acima, segue um resumo sobre os redirecionamentos:
EDIT: Este gráfico não está totalmente correto, mas não sei por que ...
O gráfico diz que 2> & 1 tem o mesmo efeito que &> no entanto
fonte
Receio que sua compreensão seja completamente invertida. :)
Pense em "entrada padrão", "saída padrão" e "erro padrão" da perspectiva do programa , não da perspectiva do kernel.
Quando um programa precisa imprimir a saída, normalmente imprime na "saída padrão". Normalmente, um programa imprime a saída na saída padrão
printf
, que imprime SOMENTE na saída padrão.Quando um programa precisa imprimir informações de erro (não necessariamente exceções, essas são uma construção da linguagem de programação, imposta em um nível muito mais alto), normalmente é impresso como "erro padrão". Normalmente, faz isso com
fprintf
, que aceita um fluxo de arquivos para usar na impressão. O fluxo de arquivos pode ser qualquer arquivo aberto para gravação: saída padrão, erro padrão ou qualquer outro arquivo que tenha sido aberto comfopen
oufdopen
."entrada padrão" é usado quando o arquivo precisa ler a entrada, usando
fread
oufgets
, ougetchar
.Qualquer um desses arquivos pode ser facilmente redirecionado do shell, assim:
Ou toda a enchilada:
Há duas advertências importantes: primeiro, "entrada padrão", "saída padrão" e "erro padrão" são apenas uma convenção. Eles são uma convenção muito forte , mas é apenas um acordo que é muito bom poder executar programas como este:
grep echo /etc/services | awk '{print $2;}' | sort
e ter as saídas padrão de cada programa conectadas à entrada padrão do próximo programa no pipeline.Segundo, forneci as funções ISO C padrão para trabalhar com fluxos de arquivos (
FILE *
objetos) - no nível do kernel, são todos os descritores de arquivos (int
referências à tabela de arquivos) e operações de nível muito inferior, comoread
ewrite
, que não são faça o buffer feliz das funções ISO C. Eu pensei em simplificar e usar as funções mais fáceis, mas pensei que você deveria conhecer as alternativas. :)fonte
stdin
Lê a entrada através do console (por exemplo, entrada do teclado). Usado em C com scanf
stdout
Produz saída para o console. Usado em C com printf
stderr
Produz saída de 'erro' para o console. Usado em C com fprintf
Redirecionamento
A fonte do stdin pode ser redirecionada. Por exemplo, em vez de vir da entrada do teclado, ela pode vir de um arquivo (
echo < file.txt
) ou de outro programa (ps | grep <userid>
).Os destinos para stdout, stderr também podem ser redirecionados. Por exemplo, stdout pode ser redirecionado para um arquivo:
ls . > ls-output.txt
nesse caso, a saída é gravada no arquivols-output.txt
. Stderr pode ser redirecionado com2>
.fonte
Acho que as pessoas que dizem que
stderr
devem ser usadas apenas para mensagens de erro são enganosas.Também deve ser usado para mensagens informativas destinadas ao usuário que está executando o comando e não a possíveis consumidores a jusante dos dados (por exemplo, se você executa um pipe de shell encadeando vários comandos, não deseja mensagens informativas como "obter o item 30 de 42424 "para aparecer,
stdout
pois eles confundirão o consumidor, mas você ainda pode querer que o usuário os veja.Veja isto para a lógica histórica:
fonte
O uso do ps -aux revela os processos atuais, todos listados em / proc / as / proc / (pid) /, chamando cat / proc / (pid) / fd / 0 e imprime qualquer coisa encontrada na saída padrão do esse processo eu acho. Então talvez,
/ proc / (pid) / fd / 0 - Arquivo de saída padrão
/ proc / (pid) / fd / 1 - Arquivo de entrada padrão
/ proc / (pid) / fd / 2 - Arquivo de erro padrão
por exemplo
Mas isso só funcionou bem para / bin / bash outros processos geralmente não tinham nada em 0, mas muitos tinham erros escritos em 2
fonte
Para obter informações oficiais sobre esses arquivos, consulte as páginas do manual, execute o comando no seu terminal.
Mas, para uma resposta simples, cada arquivo é para:
stdout para um fluxo de saída
stdin para uma entrada de fluxo
stderr para erros de impressão ou mensagens de log.
Cada programa unix possui cada um desses fluxos.
fonte
O stderr não executará o buffer do IO Cache; portanto, se nosso aplicativo precisar imprimir informações críticas de mensagens (alguns erros, exceções) no console ou no arquivo, use-o onde antes de escrever nossas mensagens no arquivo, o aplicativo pode fechar, deixando a depuração complexa
fonte
Um arquivo com buffer associado é chamado de fluxo e é declarado como um ponteiro para um tipo definido FILE. A função fopen () cria certos dados descritivos para um fluxo e retorna um ponteiro para designar o fluxo em todas as transações adicionais. Normalmente, existem três fluxos abertos com ponteiros constantes declarados no cabeçalho e associados aos arquivos abertos padrão. Na inicialização do programa, três fluxos são predefinidos e não precisam ser abertos explicitamente: entrada padrão (para leitura de entrada convencional), saída padrão (para gravação de saída convencional) e erro padrão (para gravação de saída de diagnóstico). Quando aberto, o fluxo de erro padrão não é totalmente armazenado em buffer; os fluxos de entrada e saída padrão são totalmente armazenados em buffer se, e somente se, o fluxo puder ser determinado para não se referir a um dispositivo interativo
https://www.mkssoftware.com/docs/man5/stdio.5.asp
fonte