O que é um descritor de arquivo?

Um descritor de arquivo é um número que identifica exclusivamente um arquivo aberto no sistema operacional de um computador. Ele descreve um recurso de dados e como esse recurso pode ser acessado.

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).

NomeDescritor de arquivoDescriçãoAbreviação
Entrada padrão0O 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ão1O 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ão2O 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