Como (e por que) usar o stderr para leitura e escrita?

12

De acordo com esta resposta de schily , lesslê os comandos de navegação do stderr se ele não conseguir abrir /dev/tty.

Isso parece intrigante, já que eu nunca vi nada escrever no fluxo stderr de outro programa e nem sei como conseguiria isso.

Qual é o propósito do stderr ser aberto tanto para leitura quanto para escrita? E se isso for útil, como utilizá-lo em sistemas modernos? (Existe alguma sintaxe misteriosa para inserir algo no stderr em vez de stdin, por exemplo?)

Draconis
fonte

Respostas:

7

Fiquei surpreso no começo. No entanto, depois de ler as respostas e fazer uma pequena investigação, parece simples. Então aqui está o que eu encontrei. (no final, não houve surpresa.)

Antes do redirecionamento, stdin, stdout e stderr estão, conforme o esperado, conectados ao mesmo dispositivo.

#ctrl-alt-delor:~$
#↳ ll /dev/std*
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stderr -> /proc/self/fd/2
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdin -> /proc/self/fd/0
lrwxrwxrwx 1 root root 15 Jun  3 20:58 /dev/stdout -> /proc/self/fd/1

#ctrl-alt-delor:~$
#↳ ll /proc/self/fd/*
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/0 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/1 -> /dev/pts/12
lrwx------ 1 richard richard 64 Jun 30 19:14 /proc/self/fd/2 -> /dev/pts/12

Portanto, após a maioria das reorientações (isto é, se stderr) não é redirecionado. O stderr ainda está conectado ao terminal. Portanto, pode ser lido, para obter a entrada do teclado.

A única coisa que interrompe os arquivos que estão sendo usados ​​na direção inesperada é a convenção e os tubos são unidirecionais.

Outro exemplo, tente:

cat | less

Isso dá errado após uma página, quando lesstenta ler o terminal (isso não é uma surpresa, como cattambém está lendo o terminal).

/dev/ttyé mais misterioso, não é um link para /proc/self.

#ctrl-alt-delor:~$
#↳ ll /dev/tty
crw-rw-rw- 1 root tty 5, 0 Jun 29 09:18 /dev/tty

Veja quais são as relações entre o meu terminal de controle atual e o `/ dev / tty`? para uma explicação. Obrigado a @StephenKitt pelo link.

ctrl-alt-delor
fonte
A respeito /dev/tty, veja esta pergunta .
Stephen Kitt
6

Quando você faz login, stdin, stdout e stderr são conectados ao terminal a partir do qual você faz login. Para ser mais exato, o tty é normalmente aberto e stdout e stderr são o resultado de duas dup(2)operações no primeiro descritor de arquivo. Isso permite a leitura do stderr para obter informações do terminal.

Conforme mencionado na outra resposta, os programas são lidos no stderr para obter uma resposta interativa a uma pergunta.

Como um usuário não pode saber sob quais circunstâncias um programa lê do stderr, é uma tentativa inútil de gravar intencionalmente dados no stderr de outro programa.

Observe que hoje os programas geralmente tentam abrir /dev/ttye usar o stderr apenas no caso de isso não funcionar.

Programas que apenas lêem do stderr nunca foram modificados desde antes de 1979 e geralmente contêm construções como:

int i 1;

ou

i =* 2;

que não são aceitos pelos compiladores C modernos. Como resultado, é muito improvável que hoje você encontre um programa que nunca abre, /dev/ttymas lê respostas interativas do stderr.

esperto
fonte
Então, se eu estou entendendo direito, o shell se conecta stderrao tty quando stdiné redirecionado (via pipe ou outros meios)? Ou apenas sempre se conecta stderrao tty?
Draconis
1
Quando você faz login, o stderr é conectado ao seu terminal de login.
schily
2
i =+ 1é perfeitamente válido C e é igual a i = (+1). É verdade que o primeiro é um bom candidato para o concurso C secreto.
G. Sliepen
1
OK, pode ser que apenas crie um aviso. Mudei o código para outra coisa de C em 1977.
Schily
1
Parece que eu estou ciente de mais conchas, já que eu não sei de pelo menos um shell que lê a partir diferente de sua entrada padrão . (-:
JdeBP 01/07/19