Domanda

Sto dando un'occhiata al codice per l'utilità 'less', in particolare come ottiene l'input da tastiera. È interessante notare che alla riga 80 di ttyin.c, imposta il descrittore di file da cui leggere:

     /*
      * Try /dev/tty.
      * If that doesn't work, use file descriptor 2,
      * which in Unix is usually attached to the screen,
      * but also usually lets you read from the keyboard.
      */
  #if OS2
      /* The __open() system call translates "/dev/tty" to "con". */
      tty = __open("/dev/tty", OPEN_READ);
  #else
      tty = open("/dev/tty", OPEN_READ);
  #endif
      if (tty < 0)
          tty = 2;

Il descrittore di file non è 2 stderr? Se è così, WTH ?! Pensavo che l'input da tastiera fosse inviato tramite stdin.

È interessante notare che, anche se lo fai ls -l * | less, al termine del caricamento del file, puoi comunque utilizzare la tastiera per scorrere verso l'alto e verso il basso, ma se lo fai ls -l * | vi, allora vi urlerà perché non lo fa letto da stdin. Qual è la grande idea? Come sono finito in questa strana nuova terra in cui stderr è sia un modo per segnalare errori sullo schermo che leggere dalla tastiera? Non credo di essere più in Kansas ...

È stato utile?

Soluzione

$ ls -l /dev/fd/
lrwx------ 1 me me 64 2009-09-17 16:52 0 -> /dev/pts/4
lrwx------ 1 me me 64 2009-09-17 16:52 1 -> /dev/pts/4
lrwx------ 1 me me 64 2009-09-17 16:52 2 -> /dev/pts/4

Quando si accede a un terminale interattivo, tutti e tre i descrittori di file standard puntano alla stessa cosa: il tuo TTY (o pseudo-TTY).

$ ls -fl /dev/std{in,out,err}
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdin -> fd/0
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stdout -> fd/1
lrwxrwxrwx 1 root root 4 2009-09-13 01:57 /dev/stderr -> fd/2

Per convenzione, leggiamo da 0 e scriviamo a 1 e 2. Tuttavia, nulla ci impedisce di fare diversamente.

Quando la shell esegue ls -l * | less, crea una pipe dal descrittore di file ls al less al descrittore di file open("/dev/tty") <=>. Ovviamente, <=> non è più in grado di leggere l'input da tastiera dell'utente dal descrittore di file <=> & # 8211; cerca di riavere il TTY come può.

Se <=> non è stato rimosso dal terminale, <=> gli assegnerà il TTY.

Tuttavia, nel caso in cui fallisca ... cosa puoi fare? <=> effettua un ultimo tentativo di ottenere il TTY, supponendo che il descrittore di file <=> sia collegato alla stessa cosa a cui sarebbe associato il descrittore di file <=>, se non fosse reindirizzato.

Questo non è a prova di errore:

$ ls -l * | setsid less 2>/dev/null

Qui, a <=> viene assegnata una propria sessione (quindi non fa più parte del gruppo di processi attivi del terminale, causando il fallimento di <=>) e il suo descrittore di file <=> è stato modificato & # 8211; ora <=> esce immediatamente, perché viene inviato a un TTY ma non riesce a ottenere alcun input dell'utente.

Altri suggerimenti

Beh ... prima di tutto, sembra che manchi la chiamata open() che apre '/ dev / tty'. Utilizza solo il descrittore di file 2 se la chiamata ad open () non riesce. Su un sistema Linux standard, e probabilmente su molti Unices, esiste "/ dev / tty" ed è improbabile che causi un errore.

In secondo luogo, il commento in alto fornisce una quantità limitata di spiegazioni sul perché ricadono nel descrittore di file 2. La mia ipotesi è che stdin, stdout e stderr siano praticamente collegati a '/ dev / tty / 'comunque, a meno che non venga reindirizzato. E dal momento che i reindirizzamenti più comuni per stdin e / o stdout (tramite piping o < / >), ma meno spesso per <=>, le probabilità sono che l'utilizzo di <=> sarebbe molto probabilmente ancora connesso alla " tastiera " ;.

La stessa domanda con una risposta alla fine della persona che l'ha posta è su linuxquestions sebbene citino una fonte leggermente diversa da less. E no, non capisco la maggior parte, quindi non posso fare a meno di questo :)

Sembra essere una funzionalità specifica di Linux che invia input da tastiera a FD 2.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top