用猫没用? [英] Useless use of cat?

查看:26
本文介绍了用猫没用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

This is probably in many FAQs - instead of using:

cat file | command

(这就是所谓的猫的无用使用),正确的做法应该是:

(which is called useless use of cat), correct way supposed to be:

command < file

在第二种正确"方式中 - 操作系统不必产生额外的进程.
尽管知道这一点,我还是继续使用无用的 cat 有两个原因.

In the 2nd, "correct" way - OS does not have to spawn an extra process.
Despite knowing that, I continued to use useless cat for 2 reasons.

  1. 更美观 - 我喜欢数据只从左到右均匀移动.并且更容易将 cat 替换为其他内容(gzcatecho、...)、添加第二个文件或插入新过滤器(pv, mbuffer, grep ...).

  1. more aesthetic - I like when data moves uniformly only from left to right. And it easier to replace cat with something else (gzcat, echo, ...), add a 2nd file or insert new filter (pv, mbuffer, grep ...).

我感觉"在某些情况下它可能会更快.更快,因为有 2 个进程,第一个 (cat) 执行读取,第二个执行任何操作.它们可以并行运行,这意味着有时执行速度更快.

I "felt" that it might be faster in some cases. Faster because there are 2 processes, 1st (cat) does the reading and the second does whatever. And they can run in parallel, which means sometimes faster execution.

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

Is my logic correct (for 2nd reason)?

推荐答案

直到今天某个菜鸟试图将 UUOC 我的答案之一.这是一个 cat file.txt |grep foo |切... |切....我给了他一点我的想法,只有在这样做之后才访问了他给我的链接,其中提到了该奖项的起源和这样做的做法.进一步的搜索使我想到了这个问题.有点遗憾的是,尽管经过深思熟虑,但没有一个答案包含我的理由.

I was not aware of the award until today when some rookie tried to pin the UUOC on me for one of my answers. It was a cat file.txt | grep foo | cut ... | cut .... I gave him a piece of my mind, and only after doing so visited the link he gave me referring to the origins of the award and the practice of doing so. Further searching led me to this question. Somewhat unfortunately despite conscious consideration, none of the answers included my rationale.

我本不想在回应他时采取防御态度.毕竟,在我年轻的时候,我会把命令写成 grep foo file.txt |切... |cut ... 因为每当您执行频繁的单个 grep 操作时,您都会了解文件参数的位置,并且已经知道第一个是模式,后面的是文件名.

I had not meant to be defensive in responding to him. After all, in my younger years, I would have written the command as grep foo file.txt | cut ... | cut ... because whenever you do the frequent single greps you learn the placement of the file argument and it is ready knowledge that the first is the pattern and the later ones are file names.

当我回答这个问题时,使用 cat 是一个有意识的选择,部分原因是品味"的原因(用 Linus Torvalds 的话),但主要是功能的一个令人信服的原因.

It was a conscious choice to use cat when I answered the question, partly because of a reason of "good taste" (in the words of Linus Torvalds) but chiefly for a compelling reason of function.

后一个原因更重要,所以我先说出来.当我提供管道作为解决方案时,我希望它是可重用的.很可能在另一条管道的末尾添加或拼接一条管道.在那种情况下,使用 grep 的文件参数会破坏可重用性,并且很可能会悄悄这样做,如果文件参数存在,则不会出现错误消息.IE.grep foo xyz |grep 栏 xyz |wc 将为您提供 xyz 中有多少行包含 bar 而您期望包含 foo 和 <代码>条形.在使用管道之前必须更改命令的参数很容易出错.再加上无声失败的可能性,它就变成了一种特别阴险的做法.

The latter reason is more important so I will put it out first. When I offer a pipeline as a solution I expect it to be reusable. It is quite likely that a pipeline would be added at the end of or spliced into another pipeline. In that case having a file argument to grep screws up reusability, and quite possibly do so silently without an error message if the file argument exists. I. e. grep foo xyz | grep bar xyz | wc will give you how many lines in xyz contain bar while you are expecting the number of lines that contain both foo and bar. Having to change arguments to a command in a pipeline before using it is prone to errors. Add to it the possibility of silent failures and it becomes a particularly insidious practice.

前一个原因也不是不重要,因为很多味道不错"只是对于诸如上述无声失败之类的事情的直观潜意识基本原理,当某些需要教育的人说但那只猫不是无用的"时,您无法想到正确的方法.

The former reason is not unimportant either since a lot of "good taste" merely is an intuitive subconscious rationale for things like the silent failures above that you cannot think of right at the moment when some person in need of education says "but isn't that cat useless".

不过,我也会尽量注意我之前提到的好品味"的原因.这个原因与 Unix 的正交设计精神有关.grep 不会cutls 不会grep.因此,至少 grep foo file1 file2 file3 违背了设计精神.这样做的正交方式是 cat file1 file2 file3 |grep foo.现在,grep foo file1 只是 grep foo file1 file2 file3 的一个特例,如果你不一样对待它,你至少在尝试用尽大脑时钟周期避免无用的猫奖.

However, I will try to also make conscious the former "good taste" reason I mentioned. That reason has to do with the orthogonal design spirit of Unix. grep does not cut and ls does not grep. Therefore at the very least grep foo file1 file2 file3 goes against the design spirit. The orthogonal way of doing it is cat file1 file2 file3 | grep foo. Now, grep foo file1 is merely a special case of grep foo file1 file2 file3, and if you do not treat it the same you are at least using up brain clock cycles trying to avoid the useless cat award.

这导致我们的论点是 grep foo file1 file2 file3 是串联的,而 cat 是串联的,所以它适用于 cat file1 file2 file3 但是因为 cat 没有连接到 cat file1 |grep foo 因此我们违反了 cat 和全能的 Unix 的精神.好吧,如果是这种情况,那么 Unix 将需要一个不同的命令来读取一个文件的输出并将其吐出到标准输出(而不是对其进行分页或任何纯粹的吐出到标准输出).所以你会有这样的情况,你说cat file1 file2 或者你说dog file1 并认真记住避开cat file1 以避免获得奖励,同时也避免了 dog file1 file2 因为如果指定了多个文件,dog 的设计可能会抛出错误.

That leads us to the argument that grep foo file1 file2 file3 is concatenating, and cat concatenates so it is proper to cat file1 file2 file3 but because cat is not concatenating in cat file1 | grep foo therefore we are violating the spirit of both the cat and the almighty Unix. Well, if that were the case then Unix would need a different command to read the output of one file and spit it to stdout (not paginate it or anything just a pure spit to stdout). So you would have the situation where you say cat file1 file2 or you say dog file1 and conscientiously remember to avoid cat file1 to avoid getting the award, while also avoiding dog file1 file2 since hopefully the design of dog would throw an error if multiple files are specified.

希望在这一点上,您对 Unix 设计者表示同情,因为他们没有包含一个单独的命令来将文件输出到 stdout,同时还将 cat 命名为 concatenate 而不是给它一些其他名称.<edit> 去掉了对<的错误注释,实际上<是一个高效的无拷贝将文件输出到标准输出的工具,您可以将其定位在管道的开头,因此 Unix 设计者确实为此包含了一些专门用于 </edit>

Hopefully, at this point, you sympathize with the Unix designers for not including a separate command to spit a file to stdout, while also naming cat for concatenate rather than giving it some other name. <edit> removed incorrect comments on <, in fact, < is an efficient no-copy facility to spit a file to stdout which you can position at the beginning of a pipeline so the Unix designers did include something specifically for this </edit>

下一个问题是为什么让命令只输出一个文件或将几个文件连接到标准输出而不进行任何进一步处理很重要?一个原因是避免让对标准输入进行操作的每个 Unix 命令都知道如何解析至少一个命令行文件参数并将其用作输入(如果存在).第二个原因是为了避免用户必须记住:(a) 文件名参数在哪里;(b) 避免上面提到的静默管道错误.

The next question is why is it important to have commands that merely spit a file or the concatenation of several files to stdout, without any further processing? One reason is to avoid having every single Unix command that operates on standard input to know how to parse at least one command line file argument and use it as input if it exists. The second reason is to avoid users having to remember: (a) where the filename arguments go; and (b) avoid the silent pipeline bug as mentioned above.

这让我们明白了为什么 grep 确实有额外的逻辑.其基本原理是允许用户流畅地使用独立基础(而不是作为管道)经常使用的命令.它是正交性的轻微折衷,以显着提高可用性.并不是所有的命令都应该这样设计,不经常使用的命令应该完全避免文件参数的额外逻辑(记住额外的逻辑会导致不必要的脆弱性(错误的可能性)).例外是允许文件参数,如 grep 的情况.(顺便说一句,请注意 ls 有一个完全不同的原因,不仅接受而且几乎需要文件参数)

That brings us to why grep does have the extra logic. The rationale is to allow user-fluency for commands that are used frequently and on a stand-alone basis (rather than as a pipeline). It is a slight compromise of orthogonality for a significant gain in usability. Not all commands should be designed this way and commands that are not frequently used should completely avoid the extra logic of file arguments (remember extra logic leads to unnecessary fragility (the possibility of a bug)). The exception is to allow file arguments like in the case of grep. (By the way, note that ls has a completely different reason to not just accept but pretty much require file arguments)

最后,如果标准输入在 file参数已指定.

Finally, what could have been done better is if such exceptional commands as grep (but not necessarily ls) generate an error if the standard input is also available when file arguments are specified.

这篇关于用猫没用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆