为什么 wc 根据 stdin 连接方式输出不同的填充空间?

问题描述 投票:0回答:1

请参阅以下两个命令及其输出:

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读取吗?

bash pipe stdin wc
1个回答
0
投票

简短的回答:因为使用

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
© www.soinside.com 2019 - 2024. All rights reserved.