Come (e perché) usare stderr sia per leggere che per scrivere?


12

Secondo questa risposta di schily , lesslegge i comandi di navigazione di stderr se non è in grado di aprirsi /dev/tty.

Questo sembra sconcertante, dal momento che non ho mai visto nulla scrivere sul flusso stderr di un altro programma, e non so come avrei potuto farlo.

Qual è lo scopo dell'apertura di stderr sia per la lettura che per la scrittura? E se questo è utile, come posso utilizzarlo su sistemi moderni? (Esiste una sintassi arcana per convogliare qualcosa in stderr invece che in stdin, per esempio?)

Risposte:


7

All'inizio sono stato sorpreso. Tuttavia, dopo aver letto le risposte e fatto una piccola indagine, sembra semplice. Quindi ecco quello che ho trovato. (alla fine non c'è stata sorpresa.)

Prima del reindirizzamento stdin, stdout e stderr sono come previsto connessi allo stesso 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

Pertanto, dopo la maggior parte delle direzioni secondarie (ovvero se stderr) non viene reindirizzato. stderr è ancora collegato al terminale. Pertanto può essere letto per ottenere l'input da tastiera.

L'unica cosa che sta fermando i file utilizzati nella direzione inaspettata è la convenzione, e le pipe sono unidirezionali.

Un altro esempio, prova:

cat | less

Questo va storto dopo una pagina, quando lesstenta di leggere il terminale (questa non è una sorpresa, come catsta leggendo anche il terminale).

/dev/ttyè più misterioso, non è un collegamento in /proc/self.

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

Vedi quali sono le relazioni tra il mio attuale terminale di controllo e `/ dev / tty`? per una spiegazione. Grazie a @StephenKitt per il link.


Per quanto riguarda /dev/tty, vedi questa domanda .
Stephen Kitt,

6

Quando si accede, stdin, stdout e stderr sono collegati al terminale da cui si accede. Per essere più precisi, il tty viene tipicamente aperto e stdout e stderr sono il risultato di due dup(2)operazioni sul primo descrittore di file. Ciò consente di leggere da stderr per ottenere input dal termnal.

Come menzionato nell'altra risposta, i programmi leggono da stderr per ottenere una risposta interattiva su una domanda.

Poiché un utente non può sapere in quali circostanze un programma legge da stderr, è un tentativo inutile di scrivere intenzionalmente dati in stderr da un altro programma.

Nota che oggi i programmi di solito provano prima ad aprire /dev/ttye usare stderr solo nel caso in cui non funzioni.

I programmi che leggono solo da stderr di solito non sono mai stati modificati da prima del 1979 e tali programmi di solito contengono costrutti come:

int i 1;

o

i =* 2;

che non sono accettati dai moderni compilatori C. Di conseguenza, è molto improbabile che oggi troverai un programma che non si apre mai, /dev/ttyma piuttosto legge risposte interattive da stderr.


Quindi, se sto capendo bene, la shell si connette stderral tty quando stdinviene reindirizzato (tramite pipe o altri mezzi)? O ti connetti sempre stderral tty?
Draconis,

1
Quando accedi, stderr è collegato al tuo terminale di accesso.
schily

2
i =+ 1è perfettamente valido C ed è uguale a i = (+1). Certo, il primo è un bel candidato per il subdolo concorso C.
G. Sliepen,

1
OK, è possibile che crei solo un avviso. Ho cambiato il codice in qualcos'altro da C nel 1977.
schily

1
Sembra di essere a conoscenza di più conchiglie, dal momento che io non so di almeno un guscio che legge da diverso dal suo standard input . (-:
JdeBP
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.