猫の無駄な使い方?



Useless Use Cat



解決:

何人かの新人が私の答えの1つのために私にUUOCを固定しようとした今日まで、私は賞に気づいていませんでした。そうでしたcat file.txt | grep foo |カット... |カット....私は彼に私の心の一部を与えました、そしてそうした後、彼は賞の起源とそうすることの実践について言及して私に与えたリンクを訪問しました。さらに検索すると、この質問にたどり着きました。やや残念ながら、意識的な検討にもかかわらず、どの答えにも私の論理的根拠は含まれていませんでした。

私は彼に対応するのに防御的であるつもりはなかった。結局のところ、私の若い年には、私はコマンドを次のように書いていただろうgrep foo file.txt |カット... |カット...あなたが頻繁にシングルをするときはいつでもファイル引数の配置を学習すると、最初の引数がパターンで、後のパターンがファイル名であることがわかります。



使用することは意識的な選択でした私が質問に答えたときの猫は、部分的には「美味しさ」(Linus Torvaldsの言葉で)の理由のためですが、主に機能の説得力のある理由のためです。

後者の理由がより重要なので、最初にそれを出します。私がソリューションとしてパイプラインを提供するとき、私はそれが再利用可能であることを期待しています。パイプラインが別のパイプラインの最後に追加されるか、別のパイプラインに接続される可能性が非常に高くなります。その場合、grepへのファイル引数があると再利用性が台無しになり、おそらくそうするでしょう 静かに ファイル引数が存在する場合、エラーメッセージなし。 NS。grep foo xyz | grep bar xyz | wcはあなたに何行を与えるでしょうxyzには両方を含む行数を期待している間のバーfooとバー。パイプラインでコマンドを使用する前に引数を変更する必要があると、エラーが発生しやすくなります。それにサイレント障害の可能性を追加すると、それは特に陰湿な慣行になります。



前者の理由も重要ではありません。なぜなら、多くの「美味しさ」は、教育を必要としている人が「しかしそうではない」と言った瞬間には考えられない上記の無言の失敗のようなものの直感的な潜在意識の論理的根拠にすぎないからです。あの猫は役に立たない」。

ただ、先ほど申し上げた「美味しさ」の理由も意識させていただきたいと思います。その理由は、Unixの直交設計精神と関係があります。grepはしませんカットしてlsはしませんgrep。したがって、少なくともgrep foo file1 file2file3はデザインスピリットに反します。それを行う直交する方法はcat file1 file2 file3 | grepfoo。今、grep foo file1は、grep foo file1 file2 file3、そしてあなたがそれを同じように扱わないならば、あなたは少なくとも無駄な猫賞を避けようとして脳時計サイクルを使い果たしています。

それは私たちを次のような議論に導きますgrep foo file1 file2 file3は連結しており、猫は連結するので、cat file1 file2 file3しかし、猫は連結していませんcat file1 | grep fooしたがって、両方の精神に違反しています。猫と全能のUnix。そうだとすれば、Unixは、1つのファイルの出力を読み取り、それをstdoutに吐き出すために別のコマンドを必要とします(それをページングしたり、stdoutに純粋に吐き出したりすることはありません)。だからあなたはあなたが言う状況になるでしょうcat file1file2またはあなたが言う犬file1と誠実に避けることを忘れないでくださいcat file1は、賞の獲得を回避すると同時に、回避します犬file1file2うまくいけばのデザイン以来複数のファイルが指定されている場合、dogはエラーをスローします。



うまくいけば、この時点で、ファイルをstdoutに吐き出すための個別のコマンドを含めず、名前を付けることについて、Unix設計者に同情するでしょう。他の名前を付けるのではなく、連結するための猫。 の誤ったコメントを削除しました<, 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

次の質問は、それ以上の処理を行わずに、ファイルを吐き出すだけのコマンド、または複数のファイルを連結してstdoutするコマンドを使用することが重要なのはなぜですか。 1つの理由は、標準入力で動作するすべてのUnixコマンドが、少なくとも1つのコマンドラインファイル引数を解析し、存在する場合はそれを入力として使用する方法を知ることを避けるためです。 2番目の理由は、ユーザーが次のことを覚えておく必要がないようにするためです。(a)ファイル名の引数の行き先。 (b)上記のサイレントパイプラインのバグを回避します。

それが私たちに理由をもたらしますgrepには追加のロジックがあります。理論的根拠は、頻繁に使用されるコマンドをユーザーが流暢に使用できるようにすることです。 スタンドアロン 基礎(パイプラインとしてではなく)。これは、使いやすさを大幅に向上させるための直交性のわずかな妥協点です。すべてのコマンドをこのように設計する必要はなく、頻繁に使用されないコマンドは、ファイル引数の余分なロジックを完全に回避する必要があります(余分なロジックは不要な脆弱性(バグの可能性)につながることを忘れないでください)。例外は、次の場合のようにファイル引数を許可することです。grep。 (ちなみに、注意してくださいlsには、受け入れるだけでなく、ファイル引数をほとんど必要とするまったく異なる理由があります)

最後に、もっとうまくできたのは、次のような例外的なコマンドがあった場合です。grep(ただし、必ずしもそうとは限りません)ls)ファイル引数が指定されているときに標準入力も使用できる場合、エラーが生成されます。


いいえ!

まず第一に、コマンドのどこでリダイレクトが発生するかは問題ではありません。したがって、コマンドの左側へのリダイレクトが好きな場合は、それで問題ありません。

と同じです

指図第二に、 n + 1 パイプを使用すると、プロセスとサブシェルが発生します。それは最も明らかに遅いです。ある場合には NS ゼロになっているはずなので(たとえば、組み込みのシェルにリダイレクトする場合)、猫あなたは完全に不必要に新しいプロセスを追加しています。

一般化として、パイプを使用していることに気付いたときはいつでも、それを排除できるかどうかを確認するのに30秒かかる価値があります。 (ただし、おそらく30秒より長くかかる価値はありません。)パイプとプロセスが不必要に頻繁に使用されるいくつかの例を次に示します。

$(cat somefile);の単語の場合…#$(の単語の場合自由に編集して、例を追加してください。


私は、過度に独善的なUUOC賞のほとんどの事例に同意しません。なぜなら、他の誰かに教えるとき、catは、議論されている問題またはタスクに適した出力を生成するコマンドまたはコマンドの無愛想な複雑なパイプラインの便利なプレースホルダーです。

これは、Stack Overflow、ServerFault、Unix&Linux、または任意のSEサイトなどのサイトに特に当てはまります。

誰かが特に最適化について質問した場合、またはそれに関する追加情報を追加したい場合は、猫の使用が非効率的である方法について話してください。しかし、彼らは彼らの例では、look-at-me-how-cool-am-iではなく、単純さと理解のしやすさを目指すことを選んだので、人々を怒らせないでください!複雑。

要するに、猫は必ずしも猫ではないからです。

また、UUOCの授与を楽しんでいるほとんどの人は、人々を助けたり教えたりすることよりも、自分がどれほど「賢い」かを誇示することに関心があるためにそうしています。実際には、彼らはおそらく彼らが仲間を打ち負かすための小さな棒を見つけたもう一人の初心者であることを示しています。


アップデート

https://unix.stackexchange.com/a/301194/7696の回答に投稿した別のUUOCは次のとおりです。

sqlq()local filter filter = 'cat'#非常にプリミティブです。リアルオプションの処理にはgetoptsを使用してください。 if ['$ 1' == '-delete-blank-lines']; then filter = 'grep -v' ^ $ '' shift fi#各引数は個別のコマンドとしてsqlplusにパイプされますprintf '%s  n' '[メール保護]'

UUOCの衒学者は、簡単に作成できるので、それはUUOCだと言うでしょう。$ filterはデフォルトで空の文字列になり、ifステートメントdofilter = '| grep -v '^ $' 'しかしIMO、パイプ文字をに埋め込まないことによる$ filter、これは「役に立たない」catは、次の事実を自己文書化するという非常に便利な目的を果たします。$ filter on theprintf行は単なる別の議論ではありませんsqlplusは、オプションのユーザー選択可能な出力フィルターです。

複数のオプションの出力フィルターが必要な場合は、オプション処理で追加できます。|何でも必要に応じて$ filterを追加-1つ追加パイプライン内の猫は、何かを傷つけたり、パフォーマンスの顕著な低下を引き起こしたりすることはありません。