Unix cat文件|。。。对&书信电报;文件

Unix cat文件|。。。对&书信电报;文件,unix,shell,pipe,puzzle,Unix,Shell,Pipe,Puzzle,是否存在…或cat file |…行为与不同的上下文情况 cat file |启动第二种情况下不必启动的另一个程序(cat)。如果您想使用“heredocuments”,这也会让您更加困惑。但是它的行为应该是相同的。cat将允许您按顺序导入多个文件。否则,在从常规文件读取数据时,cat负责读取数据,根据需要执行,并可能以写入管道的方式约束数据。显然,内容本身被保存了下来,但其他任何东西都可能被污染。例如:块大小和数据到达时间。此外,管道本身并不总是中性的:它充当输入和…之间的额外缓冲区 使块大小

是否存在
cat file |…
行为与
不同的上下文情况 
cat file |
启动第二种情况下不必启动的另一个程序(cat)。如果您想使用“heredocuments”,这也会让您更加困惑。但是它的行为应该是相同的。

cat
将允许您按顺序导入多个文件。否则,
在从常规文件读取数据时,
cat
负责读取数据,根据需要执行,并可能以写入管道的方式约束数据。显然,内容本身被保存了下来,但其他任何东西都可能被污染。例如:块大小和数据到达时间。此外,管道本身并不总是中性的:它充当输入和
之间的额外缓冲区

使块大小问题变得明显的快捷方法:

$ 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大文件| pv>/dev/null
5,44GB 0:00:14[393MB/s][]
$pv/dev/null
5,44GB 0:00:03[1,72GB/s][==============================================>]100%

管道导致为右侧的命令调用子shell。这会干扰环境变量

cat foo | while read line
do
  ...
done
echo "$line"

while read line
do
  ...
done < foo
echo "$line"
读取行时
做
...
完成
除了其他用户发布的内容外,当使用文件的输入重定向时,标准输入是文件,但当将cat的输出传输到输入时,标准输入是包含文件内容的流。当标准输入为时,文件将能够在文件中查找,但管道不允许。通过查找zip文件并运行以下命令可以看到这一点:

zipinfo /dev/stdin < thezipfile.zip

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

a始终避免使用cat。这就像在手刹打开的情况下驾驶一样。它白白浪费CPU周期,操作系统不断地在cat进程和管道中的下一个进程之间切换上下文。如果世界上所有无用的猫都消失了,不再被发明、改造,不再由父亲传给儿子,我们就不会有全球变暖,因为我们可以轻松地生活在节省了1.21千兆瓦电力的环境中


谢谢。我现在感觉好多了。请和我一起参加我的十字军东征,以杜绝在stackoverflow上无用地使用cat。据我所知,这个网站是无用猫大量繁殖的主要原因。我不怪新手,但我想教他们。全世界的工人和新手,松开手刹,拯救地球!!!1!

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

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

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…<在shell可以打开文件之前,不会启动fifo#“prog”
cat a|U fifo|prog…#prog'和cat'正在运行(后者可能在打开时阻塞)

在实践中,这很少有关系,除非是在人为的情况下<例如,在等待输入时,code>prog
可能会定期记录日志或执行一些清理工作,即使没有可用的输入,您也可能希望执行这些工作。(为什么
prog
不够复杂,无法打开自己的输入fifo非阻塞?

如果你想问为什么在不同的地方使用一种或另一种形式,这似乎是个人偏好的问题。Kernighan和Pike在1984年指出:属于superuser.ComInterest,尽管read()使用有限的缓冲区,但无论如何,您都会遇到一些进程的最小缓冲区大小。strace显示cat在我的平台上使用32kB读取和pv 128kB。哦,嘿,我的示例实际上与问题不匹配,因为我没有使用<和pv。正在运行…@msw它将变得非常依赖于
cat
的实现,但我将尝试以不同的方式使其变得明显。@JB:在循环内设置一个变量,然后在循环后回显它。更改的值将仅在重定向表单之后保留,而不会在管道表单之后保留。另一个演示是在循环内使用
cd
,在循环后使用
pwd
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)