受賞者の一人が私の答えの1つとしてUUOCをピン留めしようとする今日まで、この賞を知っていませんでした。でしたcat file.txt | grep foo | cut ... | cut ...
。私は彼に私の心の一部を与えました、そして、そうすることをした後にだけ、彼は賞の起源とそうする習慣について言及してくれました。さらに検索すると、この質問につながりました。意識的な検討にもかかわらず、やや残念ながら、答えのどれにも私の理論的根拠は含まれていませんでした。
私は彼を教育するときに守備するつもりはありませんでした。結局のところ、私の若い年にはgrep foo file.txt | cut ... | cut ...
、頻繁にシングルを実行するたびにgrep
ファイル引数の配置を学び、最初のものがパターンであり、後のものがファイル名であることを知っているので、コマンドを書いたでしょう。
私はcat
接頭辞で質問に答えたとき、意識的に選択しました。「Linus Torvaldsの言葉で」「良い味」の理由のために部分的に、しかし主に機能の説得力のある理由のため。
後者の理由はより重要なので、最初に説明します。ソリューションとしてパイプラインを提供するとき、再利用できると期待しています。パイプラインは、最後に追加されるか、別のパイプラインにスプライスされる可能性が非常に高いです。その場合、grepへのファイル引数があると再利用性が損なわれ、ファイル引数が存在する場合はエラーメッセージなしで静かに実行される可能性が非常に高くなります。I. e。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は1つのファイルの出力を読み取り、それを標準出力に吐き出すために別のコマンドを必要とします(ページネーションや、純粋な標準出力への吐き出しではありません)。だから、あなたが言うような状況を持っているだろうcat file1 file2
か、と言うdog file1
と誠実避けるために覚えてcat file1
も回避しながら、賞を避けるためにdog file1 file2
のうまくいけば設計するのでdog
、複数のファイルが指定されている場合、エラーをスローしていました。
この時点で、ファイルをstdoutに吐き出すための別のコマンドを含めず、cat
他の名前を付けるのではなく連結するために命名することについて、Unixデザイナーに同情することを願っています。<edit>
そのような犬、不幸な<
オペレーターがいます。残念ながら、パイプラインの最後に配置すると、構成が容易になりません。最初に配置する構文的または審美的にきれいな方法はありません。また、一般的ではないため、犬から始めて、前のファイルの後に処理したい場合は別のファイル名を追加するだけでも残念です。(>
一方、半分ほど悪くはありません。最後にほぼ完璧な配置があります。通常、パイプラインの再利用可能な部分ではないため、象徴的に区別されます。)</edit>
次の質問は、それ以上の処理をせずに、単にファイルを吐くコマンド、または複数のファイルを標準出力に連結するコマンドを持つことが重要なのはなぜですか?1つの理由は、標準入力で動作するすべてのUnixコマンドが少なくとも1つのコマンドラインファイル引数を解析し、存在する場合は入力として使用する方法を知ることを避けるためです。2番目の理由は、ユーザーが覚えておく必要がないようにするためです。(b)上記のサイレントパイプラインバグを回避します。
これが、なぜgrep
追加のロジックがあるのかを示しています。その理由は、頻繁に使用されるコマンド(パイプラインとしてではなく)をスタンドアロンで使用できるようにすることです。これは、使いやすさを大幅に向上させるための直交性のわずかな妥協です。すべてのコマンドをこのように設計する必要はありません。頻繁に使用しないコマンドは、ファイル引数の余分なロジックを完全に回避する必要があります(余分なロジックは不必要な脆弱性(バグの可能性)につながります)。例外は、の場合のようにファイル引数を許可することですgrep
。(ところでls
、ファイル引数を受け入れるだけでなく、ほとんど必要とするまったく異なる理由があることに注意してください)
最後に、標準入力が利用可能な場合にgrep
(必ずしもではありませんls
)などの例外的なコマンドがエラーを生成する場合は、より良い方法があります。コマンドには、ユーザーの利便性のために万能のUnixの直交精神に違反するロジックが含まれているため、これは合理的です。ユーザーの利便性を高めるため、つまり無音障害による苦痛を防ぐために、このようなコマンドは無音障害の可能性がある場合にユーザーに警告することにより、自分の違反に違反することをためらわないでください。