没用的猫?

没用的猫?

这可能在许多常见问题中-而不是使用:

cat file | command

(这被称为对CAT的无用使用),正确的方式应该是:

command < file

在第二,“正确”的方式-操作系统不需要产生额外的进程。
尽管我知道这一点,但我继续使用无用的猫有两个原因。

  1. 更美观-我喜欢数据只从左向右一致移动。而且更容易替换cat用别的东西(gzcatecho,添加第二个文件或插入新筛选器(pvmbuffergrep ...).

  2. 我“觉得”在某些情况下可能会更快。更快,因为有两个进程,第一个(cat)阅读,第二个做任何事情。它们可以并行运行,这意味着有时执行速度更快。

我的逻辑正确吗(第二个原因)?


茅侃侃
浏览 556回答 3
3回答

HUH函数

直到今天我才意识到这个奖项,当时一些菜鸟试图将UUOC找我的答案之一。那是一个cat file.txt | grep foo | cut ... | cut ...。我给了他一个想法,然后访问了他给我的链接,他提到了这个奖项的来源和这样做的做法。进一步的研究使我想到了这个问题。有些遗憾的是,尽管有意识地考虑,但没有一个答案包括我的理由。我本不想在回应他时采取防御的态度。毕竟,在我年轻的时候,我会把命令写成grep foo file.txt | cut ... | cut ...因为无论你做什么grep我们学习了文件参数的位置,它已经知道第一个是模式,而后面的是文件名。这是一个有意识的选择cat当我回答这个问题时,部分原因是“品味好”(用LinusTorvalds的话来说),但主要是为了一个令人信服的功能原因。后一个原因更重要,所以我会先说出来。当我提供管道作为解决方案时,我希望它是可重用的。很可能会在另一条管道的末端添加一条管道,或将其拼接到另一条管道中。在这种情况下,带有grep文件参数的grep会破坏可重用性,而且很可能会这样做。静默如果文件参数存在,则没有错误消息。I.,即grep foo xyz | grep bar xyz | wc会给你多少行xyz含bar当您期望包含两者的行数时foo和bar。在使用之前,必须将参数更改为管道中的命令很容易出错。再加上沉默失败的可能性,它就变成了一种特别阴险的做法。前一个原因也并非不重要,因为“有眼光“仅仅是直觉上的潜意识的理由,像上面的沉默失败,你无法想到的时候,当某个人需要教育时,说”但那猫不是无用的“。但是,我也会努力使我提到的前一个“好品味”的原因有意识。这与Unix的正交设计精神有关。grep不cut和ls不grep。所以至少grep foo file1 file2 file3违背了设计精神。做这件事的正交方法是cat file1 file2 file3 | grep foo。现在,grep foo file1只是一个特例grep foo file1 file2 file3如果你不这样对待它,你至少是在消耗大脑的时钟周期,试图避免无用的猫奖。这就引出了我们的论点grep foo file1 file2 file3正在连接,而且cat串连,所以它是适当的cat file1 file2 file3但因为cat没有连接到cat file1 | grep foo因此我们违背了cat以及万能的Unix。如果是这样的话,那么Unix将需要一个不同的命令来读取一个文件的输出并将其吐出到stdout(而不是对其进行分页,也不只是一个纯的stdout)。所以你会遇到你说的那种情况cat file1 file2或者你说dog file1认真地记住要避免cat file1为了避免获奖,同时也要避免dog file1 file2因为希望…的设计dog如果指定多个文件,则会引发错误。希望在这一点上,您同情unix设计器没有包含一个单独的命令来向stdout吐出一个文件,同时还命名了cat而不是给它取别的名字。<edit>删除不正确的注释<事实上,<是一种高效的不复制工具,可以将文件吐出到stdout,您可以将其定位在管道的开头,因此unix设计器确实包含了一些专门用于此的内容。</edit>下一个问题是,为什么命令只是吐出一个文件或将几个文件连在一起,而不进行任何进一步的处理,这是很重要的呢?原因之一是避免让每个在标准输入上操作的Unix命令知道如何解析至少一个命令行文件参数,并在存在时将其用作输入。第二个原因是避免用户必须记住:(A)文件名参数的去处;(B)如上所述,避免沉默的管道错误。这就引出了为什么grep确实有额外的逻辑。其基本原理是允许用户流畅地使用频繁使用的命令和单枪匹马基础(而不是管道)。这是一个小妥协的正交性,以显著提高可用性。并不是所有的命令都是这样设计的,不经常使用的命令应该完全避免文件参数的额外逻辑(记住,额外的逻辑会导致不必要的脆弱性(bug的可能性)。例外情况是允许文件参数,如grep。(顺便提一下,请注意ls有一个完全不同的理由不仅接受,而且几乎需要文件参数)最后,本可以做得更好的是,如果这样的特殊命令grep(但不一定ls)如果指定文件参数时标准输入也可用,则生成错误。

慕妹3146593

不!首先,在什么地方发生重定向并不重要。因此,如果您喜欢将方向重定向到命令的左边,那很好:< somefile command是相同的command < somefile第二,有n+1进程和子外壳在使用管道时发生。这是最明显较慢的。在某些情况下n应该是零(例如,当您重定向到shell内置的时候),所以使用cat您正在添加一个完全不必要的新过程。一般说来,每当你发现自己在使用管道时,就应该花30秒的时间来看看你是否能消除它。(但可能不值得花费超过30秒的时间。)下面是一些管道和过程经常被不必要地使用的例子:for word in $(cat somefile); … # for word in $(<somefile); … (or better yet, while read < somefile)grep something |  awk stuff; # awk '/something/ stuff' (similar for sed)echo something | command; # command <<<  something (although echo would be necessary for pure POSIX)
打开App,查看更多内容
随时随地看视频慕课网APP