较少的file1 file2 | 猫-为什么起作用?


21

当我使用时,less file1 file2两个文件都显示在“较少缓冲区查看器”中,但是less file1 file2 | cat打印了两个文件的内容并附加到stdout中。怎么不知道它是否应该显示“较少的缓冲区查看器”或为下一命令生成输出到stdout?什么机制用于执行此操作?

Answers:


30

less将文本打印到标准输出。标准输出

  • 终端(/ dev / tty?)并打开默认的缓冲区查看器
  • 使用| 将管道输送到另一个程序时,通过管道 (less text | cut -d: -f1
  • 使用>()重定向到文件less text > tmp

有一个名为“ isa tty ” 的C函数,该函数检查输出是否将输出到tty(小于4.81,main.c,第112行)。如果是这样,它将使用缓冲区查看器,否则其行为类似于cat

在bash中,您可以使用test(请参阅man test

  • -t FD文件描述符FD在终端上打开
  • -p FILE存在并且是命名管道

例:

[[ -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如果STDOUT未连接到管道或重定向,则正确的是他们没有打印STDOUT已连接到管道或重定向。将所有三个脚本。呼叫bash script.shbash script.sh | catbash script.sh > file,,看看你会得到什么输出。
hvd

1
stdout不是可以“写入文件”的东西。这是你write() 要做的less不必根据其输出是文件,管道,套接字或块设备还是其他来做任何不同的事情。它不是tty才很重要,所以它的行为就像cat。(我想您知道这一点,只是选择了错误的词来解释它,但是我想我会为其他读者指出这一点)。
彼得·科德斯

因此,您的意思是说,在我的特定问题中,举止像cat的行为要少一些-或更笼统:举止像管道中的下一条命令。据我了解,我不能假定完全相同的行为也可以通过其他工具实现。
tfh

@tfh:不,less不“说明” cat下一个。cat如果stdout不是tty,它的行为就像接下来的内容一样。
彼得·科德斯

@MichaelD .:谢谢,纠正了我的回答。我只是猜测less会继续进行下去,并使用一个TCGETS来获取终端尺寸或发现它不是tty,但显然我猜错了。
彼得·科德斯

6

less检查它stdout是否是终端,并且行为是否类似cat(将stdin复制到stdout直到EOF)。

此功能使您可以编写脚本或程序,这些脚本或程序始终通过其输出(例如,--help输出)发送输出,less同时仍允许轻松重定向到文件。如果some_command --fullhelp > help.txt仍然等待stdin上的空格键翻阅文本或其他内容,它将很烂。一些命令(例如man)检查自己的输出,以决定是否通过寻呼机发送其输出。如果您运行man ls > ls.txt,它将永远不会调用您的$PAGER

less如果您在向管道中添加更多阶段时也忘记从单行代码中对其进行编辑,则该类猫的行为很方便。


less需要弄清楚终端尺寸(屏幕尺寸,要一次显示多少行)。将ioctl(2)它使用在stdout将在非终端返回ENOTTY,所以它不能避免反正处理非终端情况。 less实际上isatty(3)在检查端子尺寸之前使用,但是isatty通过尝试仅tty的ioctl并检查是否没有错误来工作。

即使是一个简单的寻呼机more(1)(至少是util-linux版本)也具有此功能,因为这可能是针对这种情况实现的最简单的理智行为。


请注意,当您将某些内容通过管道传送 less(例如grep foo bar.txt | less)时,它确实必须打开/dev/tty才能进行键盘输入。(您可以通过看到它echo foo | strace less)。

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.