OJF*_*ord 29 pipe io-redirection cat
我偶尔会看到这样的事情:
cat file | wc | cat > file2
Run Code Online (Sandbox Code Playgroud)
为什么要这样做?
结果(或性能)何时会(有利地)不同于:
cat file | wc > file2
Run Code Online (Sandbox Code Playgroud)
lar*_*sks 37
这两个例子都是cat 的无用用法。两者都等价于wc < file1 > file2. cat在此示例中没有理由使用,除非您将其cat file用作动态生成输出的临时替代品。
Sté*_*las 32
cat file | wc | cat > file2
Run Code Online (Sandbox Code Playgroud)
通常是两个无用的用途,cat因为它在功能上等同于:
< file wc > file2
Run Code Online (Sandbox Code Playgroud)
但是,可能存在以下情况:
cat file | wc -c
Run Code Online (Sandbox Code Playgroud)
超过
< file wc -c
Run Code Online (Sandbox Code Playgroud)
那就是禁用许多wc实现对常规文件所做的优化。
对于常规文件,无需读取文件的全部内容即可获取文件中的字节数,只需对其进行stat()系统调用并检索存储在 inode 中的大小即可。
现在,人们可能希望读取文件,例如,因为:
该stat()信息不能被信任(如在一些文件/proc或/sys在Linux上):
$ < /sys/class/net/lo/mtu wc -c
4096
$ cat /sys/class/net/lo/mtu | wc -c
6
Run Code Online (Sandbox Code Playgroud)当然,这些都是例外。在一般情况下,< file wc -c出于性能原因,您宁愿使用。
现在,您可以想象可能想要使用的更牵强的场景cat file | wc | cat > file2:
wc有一个 apparmor 配置文件或其他安全机制,禁止它在允许的情况下读取或写入文件cat(这是闻所未闻的)cat能够处理大(如 > 2 32字节)文件,但不能wc在该系统上处理(过去某些系统上的某些命令需要类似的东西)。wc(也是第一个cat)运行并读取整个文件(并在最后一分钟被杀死),即使file2无法打开写入。file. 虽然wc < file > file2 || :会更有意义。lsof(清单打开的文件))的事实,他从得到一个字计数file或者他存储在字计数file2。小智 17
虽然我不同意说这是“对 cat 的无用使用”的论点,但可能有以下原因:
在许多语言(包括英语)中,单词和句子是从左到右阅读的,因此以相同的方式显示数据流可以让读者看起来更自然。
第二个原因cat可能是屏蔽返回码。如:
$ wc < /etc/passw
sh: /etc/passw: Cannot find or open the file.
$ echo $?
1
Run Code Online (Sandbox Code Playgroud)
鉴于cat:
$ wc < /etc/passw | cat
sh: /etc/passw: Cannot find or open the file.
$ echo $?
0
Run Code Online (Sandbox Code Playgroud)
如果外壳已经set -e设置,这可以发挥作用。在第一个示例中,这将在之后中止 shell,wc而在后一个示例中它将继续。显然还有其他方法可以解决这个问题。
此外,这两个语句(即有或没有 cat)的性能差异可以忽略不计(尤其是在今天的机器上),如果这很重要,shell 是使用错误的语言。
让我们假设progfork 一个新的子进程并退出,新的子进程向其标准输出写入一些内容然后退出。
然后命令
prog
Run Code Online (Sandbox Code Playgroud)
不会等待子进程退出,它会提前显示 shell 提示。但是命令
prog | cat
Run Code Online (Sandbox Code Playgroud)
将等待 的标准输入上的 EOF cat,这有效地等待子进程退出。所以这是一个有用的用法cat。