meno file1 file2 | gatto - perché funziona?


21

Quando lo utilizzo less file1 file2, visualizzo entrambi i file nel "visualizzatore meno buffer", ma less file1 file2 | catstampa il contenuto di entrambi i file aggiunti a stdout. Come fa a meno a sapere se dovrebbe mostrare il "less buffer viewer" o produrre output su stdout per un comando successivo? Quale meccanismo viene utilizzato per fare questo?

Risposte:


30

lessstampa il testo su stdout. stdout va

  • ad un terminale (/ dev / tty?) e apre il visualizzatore buffer predefinito
  • attraverso un tubo quando lo si collega ad un altro programma usando | (less text | cut -d: -f1 )
  • su un file quando lo reindirizza con> ( less text > tmp)

Esiste una funzione C chiamata "isa tty " che controlla se l'uscita sta per tty (meno 4.81, main.c, linea 112). In tal caso, utilizza il visualizzatore buffer altrimenti si comporta come cat.

In bash puoi usare test (vedi man test)

  • -t Il descrittore di file FD FD viene aperto su un terminale
  • -p FILE esiste ed è una pipe denominata

Esempio:

[[ -t 1 ]] && \
    echo 'STDOUT is attached to TTY'

[[ -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a pipe'

[[ ! -t 1 && ! -p /dev/stdout ]] && \
    echo 'STDOUT is attached to a redirection'

1
@tfh Se STDOUT non è collegato a una pipe o a un reindirizzamento, è corretto che non stampino che STDOUT sia collegato a una pipe o a un reindirizzamento. Metti tutti e tre in una sceneggiatura. Chiamata bash script.sh, bash script.sh | cat, bash script.sh > file, e vedere che cosa si ottiene in uscita.
hvd,

1
stdoutnon è qualcosa che può essere "scritto in un file". È qualcosa che devi write() fare . lessnon deve fare nulla di diverso a seconda che il suo output sia un dispositivo file, pipe, socket o block o altro. Importa solo che non è una trentina, quindi si comporta come cat. (Suppongo che tu lo sapessi e abbia semplicemente scelto le parole sbagliate per spiegarlo, ma ho pensato di segnalarlo ad altri lettori).
Peter Cordes,

Quindi vuoi dire che è compito di less comportarsi come un gatto nella mia domanda specifica - o più in generale: comportarsi come il comando successivo in una pipeline. Da quello che ho capito non posso presumere che lo stesso identico comportamento sia implementato anche in uno strumento diverso.
fino al

@tfh: No, lessnon " capisce " il catprossimo. Si comporta come catindipendentemente da ciò che verrà dopo, se il suo stdout non è un tty.
Peter Cordes,

@MichaelD .: grazie, corretta la mia risposta. Ho solo immaginato che lesssarebbe andato avanti e avrei usato un TCGET per ottenere le dimensioni del terminale o scoprire che non è un tty, ma a quanto pare ho indovinato.
Peter Cordes,

6

lesscontrolla se stdoutè un terminale e si comporta comecat quando non lo è (copia stdin su stdout fino a EOF).

Questa funzione consente di scrivere script o programmi che inviano sempre l'output (ad esempio --helpoutput), lesspur consentendo un facile reindirizzamento a un file. Farebbe schifo se some_command --fullhelp > help.txtaspettasse ancora che la barra spaziatrice su stdin sfogli il testo o qualcosa del genere. Alcuni comandi (ad esempio man) verificano che il proprio output decida se inviare il proprio output tramite un cercapersone o meno. Se corri man ls > ls.txt, non invoca mai il tuo $PAGER.

lessIl comportamento simile a un gatto è utile se si dimentica di modificarlo da una riga quando si aggiungono anche più fasi a una pipeline.


lessdeve capire le dimensioni del terminale (dimensioni dello schermo, per sapere quante linee mostrare contemporaneamente). L' ioctl(2)utilizzo su stdoutrestituirà ENOTTY su un non terminale, quindi non può comunque evitare di gestire il caso non terminale. lessutilizza effettivamente isatty(3)prima di controllare le dimensioni del terminale, ma isattyfunziona provando uno ioctl solo tty e verificando l'assenza di errori.

Anche un semplice cercapersone come more(1)(almeno la versione util-linux) ha questa caratteristica, perché è probabilmente il comportamento più semplice da implementare in quel caso.


Nota che quando installi qualcosa in less (ad es. grep foo bar.txt | less), Deve aprirsi /dev/ttyper l'input da tastiera. (Puoi vederlo farlo con echo foo | strace less).

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.