【问题标题】:Why more command cannot read stdin but from piped stdin?为什么更多命令不能读取标准输入,而是从管道标准输入?
【发布时间】:2014-01-30 05:23:07
【问题描述】:

我对@9​​87654321@ 命令有疑问。通常情况下,more 无法从 stdin 读取,但使用管道它会从标准输入读取内容。

例如,当尝试执行more 命令从stdin 获取输入时,它正在拒绝。

$ more [Enter]
Usage: more [options] file...
Options:
-d        display help instead of ring bell
-f        count logical, rather than screen lines
-l        suppress pause after form feed
-p        suppress scroll, clean screen and disblay text
-c        suppress scroll, display text and clean line ends
-u        suppress underlining
-s        squeeze multiple blank lines into one
-NUM      specify the number of lines per screenful
+NUM      display file beginning from line number NUM
+/STRING  display file beginning from search string match
-V        output version information and exit

但是,这里是从管道 stdin 获取输入。

$ cat file.txt  
This is for testing purpose 
$ cat file.txt | more 
This is for testing purpose 

我想知道这是怎么回事(意思不是从stdin 读取,而是从管道stdin 读取?

【问题讨论】:

  • 管道输入STDIN
  • 想一想;寻呼机是交互式的,因此它必须能够从控制终端获取命令,这与它所显示的数据源不同。如果它的输入是终端,它怎么知道空格字符是数据还是命令?
  • 如果您让more 将您的终端读取为标准输入,并且您按下了空格键,它应该将其解释为“”以添加到其显示的数据中,还是将其解释为转到下一页?你不能写一个程序,直到你能描述它应该做什么,没有歧义。在这种情况下这是不可能的,所以程序不支持这种情况。但是more在stdin没有连接到控制终端的情况下,会很乐意将stdin作为数据源。
  • 不知怎的,我明白了。但仍有疑问,我如何(以编程方式)检查stdin 是否连接到控制终端?
  • @mata 如果我使用工具 B,关于工具 A 内部工作原理的不理解不会消失。

标签: linux unix command-line pipe


【解决方案1】:

more 区分其标准输入是来自 TTY 还是来自其他地方(管道、常规文件等)。如 cmets 中所述,如果输入来自 TTY,more 将拒绝运行,因为它需要 TTY 读取其命令击键。另一方面,cat 不是交互式的,也不会显式处理 TTY,因此它可以不关心其输入是 TTY 还是其他类型的打开文件。

根据标准输入或输出是否为 TTY,还有许多其他 Unix 实用程序的行为示例。例如,ls 将其输出格式化为多列,而 ls | cat 则没有。

【讨论】:

  • 我如何(以编程方式)检查stdin 是否连接到控制终端?
  • @SIGKILL 在 C 中,通过调用 isatty(fileno(stdin))
  • 感谢您的解释。
最近更新 更多