Comecei a aprender como o Everything Is A File TM no Linux, o que me fez pensar no que aconteceria se eu lesse literalmente em / dev / stdout:
$ cat /dev/stdout
^C
$ tail /dev/stdout
^C
( ^C
Sou eu que estou matando o programa depois de travar).
Quando tento vim
, recebo a mensagem impensável: "/ dev / stdout" não é um arquivo. Suspiro!
Então, o que dá, por que estou recebendo interrupções ou mensagens de erro quando tento ler esses "arquivos"?
Respostas:
Você não está recebendo "hangups" de
cat(1)
etail(1)
eles estão apenas bloqueando a leitura.cat(1)
aguarda a entrada e a imprime assim que vê uma linha completa:Aqui eu digitei
foo
Enterbar
EnterCTRL- D.tail(1)
aguarda a entrada e a imprime somente quando pode detectarEOF
:Aqui eu digitei novamente
foo
Enterbar
EnterCTRL- D.O Vim é o único que fornece um erro. Faz isso porque corre
stat(2)
contra/dev/stdout
e descobre que não tem oS_IFREG
bit definido./dev/stdout
é um arquivo, mas não um arquivo regular . De fato, há alguma dança no kernel para dar uma entrada no sistema de arquivos. No Linux:No OpenBSD:
No FreeBSD:
fonte
(Quase) tudo é um arquivo, mas nem tudo é um arquivo regular . Não faz sentido chamar um editor de texto em algo que seja um arquivo especial, como diretório, soquete de rede, porta serial etc.
O arquivo
/dev/stdout
pode ser uma das várias coisas, dependendo da variante unix:De qualquer forma, a abertura de
/dev/stdout
arquivos e similares cria um novo descritor de arquivo associado ao mesmo arquivo que o aplicativo já abriu no descritor de arquivo 1. “Saída padrão” significa o descritor de arquivo 1, e é apenas uma convenção que esse descritor de arquivo seja usado para saída - o kernel não se importa.Quando você executa um programa em um terminal, todos os três descritores padrão (0 = entrada padrão, 1 = saída padrão, 2 = erro padrão) são abertos no dispositivo do terminal. A leitura desse dispositivo retorna caracteres digitados pelo usuário e a gravação nesse dispositivo exibe texto na janela do terminal. (Não existe uma maneira padrão, dado um dispositivo terminal, de ler a saída que ele exibe ou injetar entrada nele.)
Quando você executa
cat /dev/stdout
, faz exatamente a mesma coisa quecat /dev/stdin
oucat /dev/stderr
, porque esses três descritores de arquivos estão conectados ao mesmo arquivo: ele dizcat
para ler no terminal. Isso é o quecat
sem argumentos também.Se você executou
cat /dev/stdout >foo
,/dev/stdout
consulte o arquivofoo
- esse comando é equivalentecat foo >foo
. Dependendo dacat
implementação, pode ocorrer um erro (a versão GNU reclama que “arquivo de entrada é arquivo de saída”) ou pode não fazer nada porque lê o arquivofoo
que está vazio (>foo
apenas o truncou). Com uma versãocat
que não detecta esse caso especial, sefoo
não estiver vazio,cat /dev/stdout >>foo
o equivalentecat foo >>foo
ao arquivo anexa o conteúdo do arquivo indefinidamente.Quando você executa
vim /dev/stdout
, ele reclama porque não sabe editar um terminal (isso simplesmente não faz sentido).fonte
cat
etail
procura conteúdo opcional seguido pelo final do arquivo./dev/stdout
permanece abertocat
etail
continue procurando.fonte