我正在 ncurses 中开发一个程序,它将从 stdin 读取,但是,在检查其他一些程序如何执行此操作时,我注意到它不一致。例如,以下两个工作正常
tail file.txt | cat
tail file.txt | cat -
虽然这些惯于除非我使用-
:
cat file.txt | vim
cat file.txt | file
-
为什么有些程序允许管道数据而有些则不允许?是否有原因?他们应该同时支持这两种方式吗?
答案1
旨在充当流过滤器,从某些输入源获取数据并逐步处理它并生成输出,通常在不带非选项参数的情况下调用时从标准输入读取。例如cat
,tail
等默认从标准输入读取。grep
、等工具sed
需要一个操作数(grep 的正则表达式,sed 的脚本),如果这是唯一的操作数,则从标准输入读取。 Vi(m) 不适合这种模式:它是一个交互式程序,而不是流过滤器,因此当您不传递任何参数时它会以交互模式启动。
file
是一个例外:它不会从 stdin 读取,除非 stdin 作为参数给出(可能通过语法-
)。我不知道为什么原作者和 POSIX 委员会都没有决定它不会从 stdin 读取。这可能是因为file
不仅关心文件内容,还关心文件类型 - file foo
报告是否foo
是目录、常规文件、符号链接等。因此,它不像其他过滤器那样完全是流过滤器,尽管它通常是如此使用。它位于grep
(流过滤器)和ls
(仅关心文件作为目录条目,而不关心文件内容)之间。
(grep -r
也关心文件类型,但这是一个比原始命令晚得多的添加。)