Come convogliare lo stdout mantenendolo sullo schermo? (e non in un file di output)


234

Vorrei convogliare l'output standard di un programma mantenendolo sullo schermo.

Con un semplice esempio ( echoutilizzare qui è solo a scopo illustrativo):

$ echo 'ee' | foo
ee <- l'uscita che vorrei vedere

So che tee potrebbe copiare stdout su file ma non è quello che voglio.
$ echo 'ee' | tee output.txt | foo

Ho provato,
$ echo 'ee' | tee /dev/stdout | fooma non funziona dal momento che l'output di tee /dev/stdoutviene convogliatofoo


6
Nota che echo 'ee' | tee /dev/stderrfunziona, quindi se il tuo requisito "sullo schermo" è soddisfatto anche da stderr, lo farà.
nh2,

Risposte:


344

Ecco una soluzione che funziona su qualsiasi implementazione Unix / Linux, supponendo che segua lo POSIXstandard. Funziona anche su alcuni ambienti non Unix cygwin.

echo 'ee' | tee /dev/tty | foo

Riferimento: The Open Group Base Specifiche Numero 7 IEEE Std 1003.1, 2013 Edition, §10.1 :

/ Dev / tty

Associato al gruppo di processi di tale processo, se presente. È utile per programmi o procedure shell che desiderano essere sicuri di scrivere messaggi o leggere dati dal terminale, indipendentemente dal modo in cui l'output è stato reindirizzato. Può anche essere utilizzato per applicazioni che richiedono il nome di un file per l'output, quando si desidera l'output digitato ed è faticoso scoprire quale terminale è attualmente in uso. In ogni processo, un sinonimo per il terminale di controllo

È stato segnalato che alcuni ambienti come Google Colab non si implementano /dev/ttypur avendo il loro ttycomando di restituire un dispositivo utilizzabile. Ecco una soluzione alternativa:

tty=$(tty)
echo 'ee' | tee $tty | foo

o con un'antica conchiglia Bourne:

tty=`tty`
echo 'ee' | tee $tty | foo

5
@static_rtti Perché ignori anno dopo anno le mie risposte al tuo commento?
jlliagre,

1
@PaulBissex /dev/ttyè un dispositivo Unix obbligatorio. Stai correndo in una prigione BSD?
jlliagre,

1
@PaulBissex Questa è un'implementazione o un bug di configurazione. / Dev è montato? Cosa mostra "ls -l / dev / tty / dev / tty * / dev"? Vedi lists.freebsd.org/pipermail/freebsd-bugs/2012-November/… forums.freebsd.org/threads/…
jlliagre,

1
E puoi farlo in cascata in teequesto modo: cat some.log | tee /dev/tty | tee -a other.log | grep -i 'foo' >> foo.loga 1) portalo tutto sulla console, 2) prendilo tutto ad un altro file, 3) prendi le foolinee a un altro file.
Jesse Chisholm,

1
Google Colab non ha /dev/tty, ma l'output di ttyè utilizzabile.
Tom Hale,

69

Un'altra cosa da provare è:

echo 'ee' | tee >(foo)

La >(foo)è una sostituzione di processo .


1
cosa succede se voglio convogliare l'output di foo su un'altra barra?
Jack Tang,

3
@JackTang - Penso che qualsiasi ulteriore connessione all'output di foodovrà far parte della sostituzione del processo. Ecco un esempio:echo 'ee' | tee file.txt >(wc -c | tr -d ' ')
Nick Chammas,

1
Questa è stata la soluzione per me su FreeBSD (no / dev / tty)
Paul Bissex,

9
@ Nick Chammas, per mantenere una pipeline normale, è possibile scambiare le uscite di tee: echo 'ee' | tee >(cat) | foo | bar.
Vaelus,

18

L'accesso a "/ dev / stdout" è negato su alcuni sistemi, ma l'accesso al terminale utente è dato da "/ dev / tty". Usando "wc" per "pippo", gli esempi sopra funzionano OK (su Linux, OSX, ecc.) Come:

% echo 'Hi' | tee /dev/tty | wc Hi 1 1 3

Per aggiungere un conteggio in fondo a un elenco di file corrispondenti, utilizzo qualcosa del tipo:
% ls [A-J]* | tee /dev/tty | wc -l

Per evitare di dover ricordare tutto questo, definisco gli alias:
% alias t tee /dev/tty
% alias wcl wc -l

così posso semplicemente dire:
% ls [A-J]* | t | wcl


POSTSCRIPT: Per il set più giovane, che potrebbe pronunciare la sua pronuncia come "titty", potrei aggiungere che "tty" era una volta l'abbreviazione comune di un terminale "teletype", che utilizzava un rotolo di carta gialla e aveva tasti rotondi che spesso incollato.


17

Provare:

$ echo 'ee' | tee /dev/stderr | foo

Se usare stderr è un'opzione, ovviamente.


8

per prima cosa devi capire il terminale associato al tuo schermo (o qualunque schermo su cui desideri visualizzare l'output):

tty

quindi puoi collegare l'output a quel terminale e reindirizzare l'altra copia attraverso il tuo programma foo:

echo ee | tee /dev/pty/2 | foo

1
oneliner: t = $ (tty) echo ee | tee $ t | pippo | bar
Jack Tang,

5
@JackTang Questo è davvero meglio ma tè inutile. Puoi usarlo echo ee | tee $(tty) | fooma ha ancora un comando inutile ( tty), dato /dev/ttyche funziona.
jlliagre,
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.