Jak przeskoczyć stdout trzymając go na ekranie? (a nie do pliku wyjściowego)

234

Chciałbym przesyłać standardowe wyjście programu zachowując je na ekranie.

Z prostym przykładem ( echoużyj tutaj tylko w celach ilustracyjnych):

$ echo 'ee' | foo
ee <- wyjście, które chciałbym zobaczyć

Wiem, że tee może skopiować standardowe wyjście do pliku, ale nie tego chcę.
$ echo 'ee' | tee output.txt | foo

Próbowałem,
$ echo 'ee' | tee /dev/stdout | fooale to nie działa, ponieważ wyjście tee /dev/stdoutjest przesyłane dofoo

gentooboontoo
źródło
6
Pamiętaj, że to echo 'ee' | tee /dev/stderrdziała, więc jeśli stderr spełnia również twoje wymagania „na ekranie” , to zrobi to.
nh2

Odpowiedzi:

344

Oto rozwiązanie, które działa na dowolnej implementacji Unix / Linux, zakładając, że zależy mu na przestrzeganiu POSIXstandardu. Działa w niektórych środowiskach innych niż Unix cygwin.

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

Odniesienie: specyfikacja podstawowa dla otwartej grupy, wydanie 7 IEEE Std 1003.1, wydanie 2013, §10.1 :

/ dev / tty

Powiązany z grupą procesów tego procesu, jeśli istnieje. Jest przydatny w przypadku programów lub procedur powłoki, które chcą mieć pewność pisania wiadomości lub odczytywania danych z terminala bez względu na to, jak przekierowano dane wyjściowe. Może być również używany w aplikacjach, które wymagają nazwy pliku do wydrukowania, gdy pożądane jest wpisanie danych wyjściowych i męczące jest ustalanie, który terminal jest aktualnie używany. W każdym procesie synonim terminala sterującego

Zgłoszono, że niektóre środowiska, takie jak Google Colab, nie wdrażają się, /dev/ttya ich ttypolecenia zwracają użyteczne urządzenie. Oto obejście:

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

lub ze starożytną skorupą Bourne'a:

tty=`tty`
echo 'ee' | tee $tty | foo
jlliagre
źródło
5
@static_rtti Dlaczego ignorujesz rok po roku moje odpowiedzi na Twój komentarz?
jlliagre
1
@PaulBissex /dev/ttyjest obowiązkowym urządzeniem uniksowym. Czy pracujesz w więzieniu BSD?
jlliagre
1
@PaulBissex To błąd implementacji lub konfiguracji. Czy zamontowano / dev? Co pokazuje „ls -l / dev / tty / dev / tty * / dev”? Zobacz lists.freebsd.org/pipermail/freebsd-bugs/2012- Listopad
jlliagre
1
Możesz kaskadować w teenastępujący sposób: cat some.log | tee /dev/tty | tee -a other.log | grep -i 'foo' >> foo.logdo 1) przenieś wszystko do konsoli, 2) dodaj wszystko do innego pliku, 3) pobierz foolinie do innego pliku.
Jesse Chisholm,
1
Google Colab nie ma /dev/tty, ale wynik ttyjest użyteczny.
Tom Hale,
69

Kolejną rzeczą do wypróbowania jest:

echo 'ee' | tee >(foo)

Jest >(foo)to podstawienie procesu .

bmk
źródło
1
co jeśli chcę przesłać wyjście foo do innego paska?
Jack Tang,
3
@JackTang - Myślę, że wszelkie dalsze potokowanie na wyjściu foobędzie musiało być częścią podstawienia procesu. Oto przykład:echo 'ee' | tee file.txt >(wc -c | tr -d ' ')
Nick Chammas
1
To było dla mnie rozwiązanie na FreeBSD (no / dev / tty)
Paul Bissex
9
@Nick Chammas, aby utrzymać normalną rurociągu, można zamienić wyjścia tee: echo 'ee' | tee >(cat) | foo | bar.
Vaelus
18

Dostęp do „/ dev / stdout” jest zabroniony w niektórych systemach, ale dostęp do terminala użytkownika zapewnia „/ dev / tty”. Używając „wc” dla „foo”, powyższe przykłady działają OK (na Linux, OSX itp.) Jako:

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

Aby dodać liczbę na dole listy pasujących plików, używam czegoś takiego:
% ls [A-J]* | tee /dev/tty | wc -l

Aby uniknąć konieczności zapamiętywania tego wszystkiego, definiuję aliasy:
% alias t tee /dev/tty
% alias wcl wc -l

żebym mógł po prostu powiedzieć:
% ls [A-J]* | t | wcl


POSTSCRIPT: Dla młodszego zestawu, który może titterować swoją wymowę jako „titty”, mógłbym dodać, że „tty” był kiedyś powszechnym skrótem terminala „teletype”, który używał rolki żółtego papieru i miał okrągłe klawisze, które często oblepiony.

użytkownik51527
źródło
17

Próbować:

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

Oczywiście użycie stderr jest opcją.

Jan
źródło
8

najpierw musisz dowiedzieć się, który terminal jest powiązany z twoim ekranem (lub którymkolwiek innym ekranem, na którym chcesz wyświetlać dane wyjściowe):

tty

następnie możesz przełączyć wyjście do tego terminala i przesłać drugą kopię przez program foo:

echo ee | tee /dev/pty/2 | foo
Michael Martinez
źródło
1
oneliner: t = $ (tty) echo ee | tee $ t | foo | bar
Jack Tang,
5
@JackTang To rzeczywiście lepsze, ale tjest bezużyteczne. Możesz użyć, echo ee | tee $(tty) | fooale nadal ma bezużyteczne polecenie ( tty), ponieważ po /dev/ttyprostu działa.
jlliagre