Як передавати stdout, зберігаючи його на екрані? (а не у вихідний файл)


234

Я хотів би передати стандартний вихід програми, зберігаючи її на екрані.

Простий приклад ( echoвикористання тут лише для ілюстрації):

$ echo 'ee' | foo
ee <- вихід, який я хотів би бачити

Я знаю, що трійник міг скопіювати stdout у файл, але це не те, що я хочу.
$ echo 'ee' | tee output.txt | foo

Я спробував,
$ echo 'ee' | tee /dev/stdout | fooале це не спрацьовує, оскільки вихід трійника до /dev/stdoutтруб єfoo


6
Зауважте, що це echo 'ee' | tee /dev/stderrпрацює, тому, якщо ваша вимога "на екрані" буде задоволена і stderr, це буде зроблено.
nh2

Відповіді:


344

Ось рішення, яке працює у будь-якій реалізації Unix / Linux, припускаючи, що воно дотримується POSIXстандарту. Він також працює в деяких середовищах, які не є Unix cygwin.

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

Довідка: Технічні характеристики бази відкритої групи Випуск 7 IEEE Std 1003.1, видання 2013 року, §10.1 :

/ dev / tty

Пов'язано з групою процесів цього процесу, якщо така є. Це корисно для програм або процедур оболонки, які хочуть бути впевненими в написанні повідомлень або зчитуванні даних з терміналу, незалежно від того, як вихід був перенаправлений. Він також може бути використаний для додатків, які вимагають ім'я файлу для виводу, коли потрібний набраний вихід, і утомити, який термінал зараз використовується. У кожному процесі синонім керуючого терміналу

Повідомлялося, що в деяких середовищах, таких як Google Colab, вони не застосовуються, /dev/ttyпоки ttyкоманда повертає придатний пристрій. Ось таке рішення:

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

або зі стародавньою оболонкою Борна:

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

5
@static_rtti Чому ви ігноруєте рік за роком мої відповіді на ваш коментар?
jlliagre

1
@PaulBissex /dev/tty- обов'язковий пристрій Unix. Ти біжиш у в'язниці BSD?
jlliagre

1
@PaulBissex Це або помилка реалізації або конфігурації. Чи встановлений / dev? Що показує "ls -l / dev / tty / dev / tty * / dev"? Див. Списки.freebsd.org/ pipermail/
jlliagre

1
І ви можете каскадувати teeтак: cat some.log | tee /dev/tty | tee -a other.log | grep -i 'foo' >> foo.log1) перенесіть все на консоль, 2) додайте все до іншого файлу, 3) отримайте fooрядки до іншого файлу.
Джессі Чизгольм

1
Google Colab не має /dev/tty, але вихід ttyкорисний.
Том Хейл

69

Ще одна річ, яку слід спробувати:

echo 'ee' | tee >(foo)

>(foo)Є заміна процесу .


1
що робити, якщо я хочу передати висновок foo на інший бар?
Джек Тан

3
@JackTang - Я думаю, що будь-які подальші трубопроводи на виході fooповинні бути частиною процесу заміни. Ось приклад:echo 'ee' | tee file.txt >(wc -c | tr -d ' ')
Нік Шамм

1
Це було рішення для мене на FreeBSD (no / dev / tty)
Пол Біссекс

9
@Nick Хаммас, щоб підтримувати нормальний трубопровід, ви можете поміняти місцями виходи трійника: echo 'ee' | tee >(cat) | foo | bar.
Ваелюс

18

У деяких системах доступ до "/ dev / stdout" заборонено, але доступ до терміналу користувача надається "/ dev / tty". Використовуючи "wc" для "foo", наведені вище приклади працюють ОК (на Linux, OSX тощо) як:

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

Щоб додати підрахунок у нижній частині списку відповідних файлів, я використовую щось на зразок:
% ls [A-J]* | tee /dev/tty | wc -l

Щоб не запам'ятати все це, я визначаю псевдоніми:
% alias t tee /dev/tty
% alias wcl wc -l

так що я можу просто сказати:
% ls [A-J]* | t | wcl


POSTSCRIPT: Для молодшого набору, який може титрувати свою вимову як "titty", я можу додати, що "tty" колись була поширеною абревіатурою для терміналу "телетайп", який використовував рулон жовтого паперу і мав круглі клавіші, які часто застряг.


17

Спробуйте:

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

Якщо використовувати stderr - це варіант, звичайно.


8

спершу вам потрібно з’ясувати термінал, пов’язаний з вашим екраном (або на якому екрані ви хочете відображати вихід):

tty

тоді ви можете підключити вихід до цього терміналу і передати іншу копію через вашу програму foo:

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

1
oneliner: t = $ (tty) echo ee | тi $ т | foo | bar
Jack Tang

5
@JackTang Це дійсно краще, але tмарно. Ви можете використовувати, echo ee | tee $(tty) | fooале він все ще має марну команду ( tty), враховуючи факт, що /dev/ttyпрацює.
jlliagre
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.