关于unix:cat文件| …vs…<文件

cat file | … vs … <file

是否存在...或上下文,其中cat file | ...的行为不同于... <file


从常规文件读取时,cat负责读取数据,并根据需要执行,并且可能会限制其将数据写入管道的方式。显然,内容本身已保留,但其他任何内容都可能被污染。例如:块大小和数据到达时间。此外,管道本身并不总是中立的:它充当输入和...之间的附加缓冲区。

使块大小问题显而易见的快速简便方法:

1
2
3
4
$ cat large-file | pv >/dev/null
5,44GB 0:00:14 [ 393MB/s] [              <=>                                  ]
$ pv <large-file >/dev/null
5,44GB 0:00:03 [1,72GB/s] [=================================>] 100%


除了其他用户发布的内容外,使用文件中的输入重定向时,标准输入是文件,但将cat的输出通过管道传递到输入时,标准输入是包含文件内容的流。当使用标准输入时,该文件将能够在该文件中进行搜索,但是管道将不允许该文件。您可以通过找到一个zip文件并运行以下命令来查看此内容:

1
zipinfo /dev/stdin < thezipfile.zip

1
cat thezipfile.zip | zipinfo /dev/stdin

第一个命令将显示zipfile的内容,而第二个命令将显示错误,尽管这是一个误导性错误,因为zipinfo不会检查seek调用的结果,并且稍后会出现错误。


cat将允许您按顺序传送多个文件。否则,<重定向和cat file |会产生相同的副作用。


总是要避免不必要地使用猫。这就像手刹开着。它浪费了CPU周期,而OS则不断在cat进程和管道中的下一个进程之间进行上下文切换。如果世界上所有无用的猫消失了,而不再发明,重新发明,从父辈传给儿子,那么我们就不会发生全球变暖,因为我们可以轻松地节省1.21吉瓦的电力。

谢谢。我现在感觉好多了。请加入我的十字军东征,以消除在stackoverflow上对猫的无用使用。据我所知,这个网站是无用猫繁殖的主要贡献。我不怪新手,但我确实想教他们。世界上的工人和新手,松开手刹,拯救地球!!!! 1!


另一个区别是对输入文件的阻塞open()的行为。

例如,假设输入是没有写程序的FIFO,则一次调用将不会生成任何子程序,直到打开输入文件为止,而另一次调用将生成两个进程:

1
2
prog ... < a_fifo      # 'prog' not launched until shell can open file
cat a_fifo | prog ...  # 'prog' and 'cat' are running (latter may block on open)

实际上,除了人为情况外,这几乎无关紧要。例如,prog可能会在等待输入时定期记录日志或进行一些清理工作,即使没有可用的输入,您可能希望发生这种情况。 (为什么prog不够复杂,无法打开自己的输入以非阻塞方式?)


管道使右侧命令中的子shell被调用。这会干扰环境变量。

1
2
3
4
5
cat foo | while read line
do
  ...
done
echo"$line"

1
2
3
4
5
while read line
do
  ...
done < foo
echo"$line"


cat file |启动另一个在第二种情况下不必启动的程序(cat)。如果您要使用"此处文档",这也会使您更加困惑。但是它的行为应该相同。