Quando um programa pede para abrir um arquivo - ou outro recurso de dados, como um soquete de rede - o kernel do sistema operacional concede acesso, cria uma entrada na tabela de arquivos global e fornece ao software a localização dessa entrada.
O descritor é identificado por um número inteiro não negativo exclusivo, como 0, 12 ou 567 . Pelo menos um descritor de arquivo existe para cada arquivo aberto no sistema.
Os descritores de arquivos foram usados pela primeira vez no Unix e são usados pelos sistemas operacionais modernos, incluindo Linux, macOS X e BSD. No Microsoft Windows, descritores de arquivo são conhecidos como identificadores de arquivo.
- visão global
- Stdin, stdout e stderr
- Redirecionando descritores de arquivos
Quando um processo faz um pedido bem-sucedido para abrir um arquivo, o kernel retorna um descritor de arquivo que aponta para uma entrada na tabela de arquivos global do kernel. A entrada da tabela de arquivos contém informações como o inode do arquivo, o byte offset e as restrições de acesso para esse fluxo de dados (somente leitura, somente gravação, etc.).
Stdin, stdout e stderr
Em um sistema operacional Unix-like, os três primeiros descritores de arquivos, por padrão, são STDIN (entrada padrão), STDOUT (saída padrão) e STDERR (erro padrão).
Nome | Descritor de arquivo | Descrição | Abreviação |
---|---|---|---|
Entrada padrão | 0 | O fluxo de dados padrão para entrada, por exemplo, em um pipeline de comando. No terminal, o padrão é a entrada do teclado do usuário. | stdin |
Saída padrão | 1 | O fluxo de dados padrão para saída, por exemplo, quando um comando imprime texto. No terminal, isso é padronizado para a tela do usuário. | stdout |
Erro padrão | 2 | O fluxo de dados padrão para saída relacionado a um erro ocorrendo. No terminal, isso é padronizado para a tela do usuário. | stderr |
Redirecionando descritores de arquivos
Os descritores de arquivos podem ser acessados diretamente usando o bash, o shell padrão do Linux, o macOS X e o Windows Subsystem para Linux.
Por exemplo, quando você usa o comando find, a saída bem-sucedida vai para stdout (descritor de arquivo 1 ) e as mensagens de erro vão para stderr (descritor de arquivo 2 ). Ambos os fluxos são exibidos como saída de terminal:
encontre / -name '* alguma coisa *'
/ usr / share / doc / alguma coisa / usr / share / doc / alguma coisa / examples / something_random find: `/ run / udisks2 ': Permissão negada find:` / run / wpa_supplicant': Permissão negada / usr / share / alguma coisa / usr / games / something
Estamos recebendo erros porque o find está tentando pesquisar alguns diretórios do sistema que não temos permissão para ler. Todas as linhas que dizem "Permissão negada" foram escritas para stderr e as outras linhas foram escritas para stdout .
Você pode ocultar o stderr redirecionando o descritor de arquivo 2 para / dev / null, o dispositivo especial no Linux que "não leva a lugar nenhum":
find / -name '* alguma coisa *' 2> / dev / null
/ usr / share / doc / alguma coisa / usr / share / doc / alguma coisa / examples / something_random / usr / share / alguma coisa / usr / games / something
Os erros foram enviados para / dev / null e não são exibidos.
Entender a diferença entre stdout e stderr é importante quando você deseja trabalhar com a saída de um programa. Por exemplo, se você tentar grep a saída do comando find, você notará que as mensagens de erro não são filtradas, porque somente a saída padrão é canalizada para o grep .
find / -name '* alguma coisa *' | grep 'alguma coisa'
/ usr / share / doc / alguma coisa / usr / share / doc / alguma coisa / examples / something_random find: `/ run / udisks2 ': Permissão negada find:` / run / wpa_supplicant': Permissão negada / usr / share / alguma coisa / usr / games / something
No entanto, você pode redirecionar o erro padrão para a saída padrão e, em seguida, o grep processará o texto de ambos:
find / -name '* alguma coisa *' 2> & 1 | grep 'alguma coisa'
/ usr / share / doc / alguma coisa / usr / share / doc / alguma coisa / examples / something_random / usr / share / alguma coisa / usr / games / something
Observe que no comando acima, o descritor de arquivo de destino ( 1 ) é prefixado com um e comercial (" & "). Para obter mais informações sobre o redirecionamento de fluxo de dados, consulte os pipelines no shell bash.
Para exemplos de criação e uso de descritores de arquivos no bash, consulte nossos exemplos de comandos do exec builtin.
Identificador de arquivo, termos do sistema operacional