如何在显示标准输出的同时将其显示在屏幕上?(而不是输出文件)


234

我想在保持程序在屏幕上的同时通过管道输出标准程序。

通过一个简单的示例(echo此处仅用于说明目的):

$ echo 'ee' | foo
ee <-我希望看到的输出

我知道tee可以将stdout复制到文件,但这不是我想要的。
$ echo 'ee' | tee output.txt | foo

我试过了,
$ echo 'ee' | tee /dev/stdout | foo但由于将tee输出/dev/stdout管道输送到foo


6
请注意,echo 'ee' | tee /dev/stderr虽然可以,但是如果stderr也满足您的“屏幕显示”要求,那就可以了。
nh2

Answers:


344

这是一个适用于任何Unix / Linux实现的解决方案,假设它愿意遵循该POSIX标准。它也可以在某些非Unix环境下工作cygwin

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

参考: 《开放组基础规范》第7版IEEE Std 1003.1,2013版,第10.1节

/ dev / tty

与该流程的流程组相关联(如果有)。对于希望确保无论如何重定向输出都希望将消息写入终端或从终端读取数据的程序或Shell过程,它都非常有用当需要键入输出时,它还可以用于要求输出文件名的应用程序,并且很难找到当前正在使用的终端。在每个过程中,控制终端的同义词

据报告,诸如Google Colab之类的某些环境/dev/tty在仍然让其tty命令返回可用设备的同时仍未实现。这是一种解决方法:

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

或带有古老的伯恩贝壳:

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

5
@static_rtti您为什么逐年忽略我对您的评论的回复?
jlliagre 2015年

1
@PaulBissex /dev/tty是必需的Unix设备。您正在BSD监狱中奔跑吗?
jlliagre

1
@PaulBissex要么是实现错误,要么是配置错误。/ dev已安装?什么显示“ ls -l / dev / tty / dev / tty * / dev”?见lists.freebsd.org/pipermail/freebsd-bugs/2012-November/... forums.freebsd.org/threads/...
jlliagre

1
您可以tee像这样层叠:cat some.log | tee /dev/tty | tee -a other.log | grep -i 'foo' >> foo.log至1)将所有内容都添加到控制台,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 ' ')
Nick Chammas 2014年

1
这是我在FreeBSD上的解决方案(无/ dev / tty)
Paul Bissex

9
@Nick Chammas,要维持正常的管道,您可以交换tee:的输出echo 'ee' | tee >(cat) | foo | bar
Vaelus '17

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”曾经是“ teletype”终端的常用缩写,该终端使用一卷黄纸,并且通常使用圆键卡住。


17

尝试:

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

当然,如果使用stderr是一种选择。


8

首先,您需要找出与屏幕(或要在其上显示输出的任何屏幕)关联的终端:

tty

然后您可以将输出发送到该终端,并通过foo程序通过管道传递其他副本:

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

1
oneliner:t = $(tty)回声ee | T恤$ t | foo | 酒吧
杰克·唐

5
@JackTang确实更好,但t没用。您可以使用,echo ee | tee $(tty) | footty鉴于实际情况,它仍然具有无用的命令()/dev/tty
jlliagre 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.