请参阅以下两个命令及其输出:
hal@DESKTOP-B3IP76D:~$ wc < myfile.txt
4 4 34
hal@DESKTOP-B3IP76D:~$ cat myfile.txt | wc
4 4 34
我的理解是,这两个都将
wc
进程的stdin与myfile.txt
的内容流连接起来。但为什么在一种情况下会填充输出,而在另一种情况下则不会? wc 如何区分两者?不就是从stdin读取吗?
简短的回答:因为使用
wc < myfile.txt
,wc
程序可以直接访问文件,并且除了读取文件之外还可以执行其他操作。具体来说,它可以获取文件的大小(并以此为基础输出列宽度)。对于 cat myfile.txt | wc
,它无法做到这一点,因此它使用宽列来确保有足够的空间。
长答案:
wc
尝试提供精美的列式输出:
$ wc a.txt b.txt
6 6 88 a.txt
60 236 1772 b.txt
66 242 1860 total
为了估计其列需要多宽,GNU 版本的
wc
在其所有输入文件上运行
stat()
(或
fstat()
)(在实际读取它们以获取详细计数之前),并使用它们的大小来确定单词/行/字符计数可能有多大,因此可能需要多宽才能使列有空间容纳所有这些数字。
如果它无法获取任何输入文件的大小(例如,因为它们不是普通文件,而是管道或类似的文件),它会“假设最坏的情况”,并强制最小宽度为 7 位数字。因此,任何时候任何的输入都是管道或类似的东西,你都会得到宽列。
一些例子:
# direct input via stdin
$ wc a.txt - <b.txt
6 6 88 a.txt
60 236 1772 -
66 242 1860 total
# indirect input via cat and a pipe on stdin
$ cat b.txt | wc a.txt -
6 6 88 a.txt
60 236 1772 -
66 242 1860 total
# direct via file descriptor #4
$ wc a.txt /dev/fd/4 4<b.txt
6 6 88 a.txt
60 236 1772 /dev/fd/4
66 242 1860 total
# indirect input via cat and a pipe on FD #63
$ wc a.txt <(cat b.txt)
6 6 88 a.txt
60 236 1772 /dev/fd/63
66 242 1860 total