为什么管道到 cat 仅用于重定向?

为什么管道到 cat 仅用于重定向?

我偶尔会看到这样的事情:

cat file | wc | cat > file2

为什么要这样做?

结果(或性能)何时会与以下简单情况有所不同(有利):

cat file | wc > file2

答案1

这两个例子都是猫的无用用途。两者都相当于wc < file1 > file2.没有理由cat在此示例中使用,除非您用作cat file动态生成输出的临时替代品。

答案2

cat file | wc | cat > file2

通常是两个无用的用途,cat因为它在功能上相当于:

< file wc > file2

但是,可能存在以下情况:

cat file | wc -c

超过

< file wc -c

wc那就是禁用许多实现对常规文件所做的优化。

对于常规文件,无需读取文件的全部内容即可获取文件中的字节数,而只需stat()对其进行系统调用并检索存储在 inode 中的大小。

现在,人们可能希望读取该文件,因为:

  • stat()信息不可信(例如 Linux 中/proc/sysLinux 上的某些文件):

    $ < /sys/class/net/lo/mtu wc -c
    4096
    $ cat /sys/class/net/lo/mtu | wc -c
    6
    
  • 人们想要检查可以读取多少数据(例如硬盘驱动器出现故障的情况)。
  • 人们只是想获得有关数据读取速度的基准。
  • 人们希望将文件的内容缓存在内存中。

当然,这些都是例外。在一般情况下,您宁愿< 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.

答案3

虽然我不同意“猫的无用用途”这一论点,但是其原因:

在许多语言(包括英语)中,单词和句子都是从左到右阅读的,因此以相同的方式显示数据流对读者来说会显得更自然。

第二个原因cat可能是屏蔽返回码。例如:

$ wc < /etc/passw
sh: /etc/passw: Cannot find or open the file.
$ echo $?
1

而与cat

$ wc < /etc/passw | cat
sh: /etc/passw: Cannot find or open the file.
$ echo $?
0

如果外壳已经凝固,这就会发挥作用set -e。在第一个示例中,这将中止 shell wc,而在后一个示例中,它将继续运行。显然还有其他方法可以解决这个问题。

另外,两个语句(即有或没有 cat)的性能差异可以忽略不计(尤其是在今天的机器上),如果它很重要,那么 shell 是错误的语言。

答案4

该语句包含 cat 的两种用法。

文件 |厕所 |> 文件2

显然第二只猫没有价值,因为

文件| wc > 文件2

在我用过的所有 shell 中都有相同的含义。

然而

<文件wc> 文件2

不适用于全部贝壳。

并非每个人都在 UNIX 调制解调器版本上使用调制解调器 shell。 (以一种适用于安装了管道中命令的所有系统的方式编写管道可能会带来好处,即使其中一些公共命令并未作为给定操作系统的标准提供。)

相关内容