Ich war mir der Auszeichnung bis heute nicht bewusst, als ein Anfänger versuchte, die UUOC für eine meiner Antworten an mich zu binden. Es war ein cat file.txt | grep foo | cut ... | cut .... Ich gab ihm einen Teil meiner Meinung und besuchte erst dann den Link, den er mir gab, um auf die Ursprünge der Auszeichnung und die Praxis hinzuweisen. Weitere Suche führte mich zu dieser Frage. Etwas unglücklicherweise enthielt trotz bewusster Überlegung keine der Antworten meine Begründung.
Ich wollte nicht defensiv sein, wenn ich ihn erziehe. Schließlich hätte ich in meinen jüngeren Jahren den Befehl so geschrieben, als grep foo file.txt | cut ... | cut ...ob Sie bei jeder häufigen Single grepdie Platzierung des Datei-Arguments lernen und wissen, dass das erste das Muster und das spätere die Dateinamen sind.
Es war eine bewusste Entscheidung, als ich die Frage mit dem catPräfix beantwortete, teilweise aus Gründen des "guten Geschmacks" (in den Worten von Linus Torvalds), hauptsächlich aber aus zwingenden Gründen der Funktion.
Der letztere Grund ist wichtiger, also werde ich ihn zuerst herausbringen. Wenn ich eine Pipeline als Lösung anbiete, erwarte ich, dass sie wiederverwendbar ist. Es ist sehr wahrscheinlich, dass eine Pipeline am Ende einer anderen Pipeline hinzugefügt oder in eine andere gespleißt wird. In diesem Fall eine Datei Argument grep vermasselt Wiederverwertbarkeit aufweisen und ganz tun vielleicht so leise , ohne eine Fehlermeldung , wenn das Dateiargument vorhanden ist . Ich e. grep foo xyz | grep bar xyz | wcgibt an, wie viele Zeilen xyzenthalten sind, barwährend Sie die Anzahl der Zeilen erwarten, die sowohl fooals auch enthalten bar. Das Ändern von Argumenten in einem Befehl in einer Pipeline vor dessen Verwendung ist fehleranfällig. Wenn Sie die Möglichkeit stiller Fehler hinzufügen, wird dies zu einer besonders heimtückischen Praxis.
Der erstere Grund ist auch nicht unwichtig, da viel "guter Geschmack" lediglich eine intuitive unbewusste Begründung für Dinge wie die oben genannten stillen Fehler ist, an die man im Moment, in dem jemand, der Bildung benötigt, sagt "aber nicht", nicht denken kann diese Katze nutzlos ".
Ich werde jedoch versuchen, auch den erwähnten früheren "guten Geschmack" bewusst zu machen. Dieser Grund hat mit dem orthogonalen Designgeist von Unix zu tun. greptut nicht cutund lstut nicht grep. Das widerspricht also zumindest grep foo file1 file2 file3dem Designgeist. Die orthogonale Vorgehensweise ist cat file1 file2 file3 | grep foo. Jetzt grep foo file1ist es nur ein Sonderfall von grep foo file1 file2 file3, und wenn Sie es nicht gleich behandeln, verbrauchen Sie zumindest die Gehirn-Taktzyklen, um den unnützen Katzenpreis zu vermeiden.
Das führt uns zu dem Argument, grep foo file1 file2 file3das verkettet und catverkettet, so dass es angemessen ist, cat file1 file2 file3aber weil cates nicht verkettet, cat file1 | grep fooverletzen wir den Geist von sowohl dem catals auch dem allmächtigen Unix. Nun, wenn das der Fall wäre, würde Unix einen anderen Befehl benötigen, um die Ausgabe einer Datei zu lesen und auf stdout zu spucken (nicht paginieren oder irgendetwas anderes, nur auf stdout spucken). Sie würden also die Situation haben, in der Sie sagen cat file1 file2oder Sie sagen dog file1und gewissenhaft daran denken, cat file1zu vermeiden, die Auszeichnung zu erhalten, und gleichzeitig zu vermeiden, dog file1 file2da das Design von hoffentlich dogeinen Fehler auslösen würde, wenn mehrere Dateien angegeben werden.
Hoffentlich sympathisieren Sie an dieser Stelle mit den Unix-Designern dafür, dass sie keinen separaten Befehl enthalten, um eine Datei in stdout zu spucken, und gleichzeitig catfür die Verkettung einen Namen vergeben, anstatt einen anderen Namen zu vergeben. <edit>da ist so ein hund, der unglückliche <betreiber. Es ist bedauerlich, dass es sich am Ende der Pipeline befindet und sich nicht leicht zusammensetzen lässt. Es gibt keine syntaktisch oder ästhetisch saubere Möglichkeit, es am Anfang zu platzieren. Es ist auch bedauerlich, nicht allgemein genug zu sein, so dass Sie mit dem Hund beginnen, aber einfach einen anderen Dateinamen hinzufügen, wenn Sie möchten, dass er auch nach dem vorherigen verarbeitet wird. (Die >ist andererseits nicht halb so schlecht. Sie hat am Ende eine nahezu perfekte Platzierung. Sie ist normalerweise kein wiederverwendbarer Teil einer Pipeline und wird dementsprechend symbolisch unterschieden.)</edit>
Die nächste Frage ist, warum es wichtig ist, Befehle zu haben, die lediglich eine Datei ausspucken oder mehrere Dateien ohne weitere Verarbeitung zu stdout verketten. Ein Grund besteht darin, zu vermeiden, dass jeder einzelne Unix-Befehl, der auf der Standardeingabe ausgeführt wird, weiß, wie mindestens ein Befehlszeilenargument analysiert und als Eingabe verwendet wird, falls vorhanden. Der zweite Grund besteht darin, zu vermeiden, dass Benutzer sich Folgendes merken müssen: (a) wohin die Dateinamenargumente führen; und (b) den oben erwähnten stillen Pipeline-Fehler vermeiden.
Das bringt uns zu dem Grund, warum grepes die zusätzliche Logik gibt. Das Grundprinzip besteht darin, für Befehle, die häufig und eigenständig (und nicht als Pipeline) verwendet werden, eine flüssige Benutzerführung zu ermöglichen . Es ist ein leichter Kompromiss der Orthogonalität für einen signifikanten Gewinn an Benutzerfreundlichkeit. Nicht alle Befehle sollten auf diese Weise entworfen werden, und Befehle, die nicht häufig verwendet werden, sollten die zusätzliche Logik von Dateiargumenten vollständig vermeiden (denken Sie daran, dass zusätzliche Logik zu unnötiger Fragilität führt (die Möglichkeit eines Fehlers)). Die Ausnahme besteht darin, Dateiargumente wie im Fall von zuzulassen grep. (Übrigens, das lshat einen ganz anderen Grund, Dateiargumente nicht nur zu akzeptieren, sondern so ziemlich zu verlangen)
Schliesslich hätte man es besser machen können, wenn solche aussergewöhnlichen Befehle grep(aber nicht notwendigerweise ls) einen Fehler erzeugen, wenn die Standardeingabe verfügbar ist. Dies ist sinnvoll, da die Befehle Logik enthalten, die den orthogonalen Geist des allmächtigen Unix für die Benutzerfreundlichkeit verletzt. Zur weiteren Bequemlichkeit des Benutzers, dh zur Verhinderung des durch einen stillen Fehler verursachten Leidens, sollten solche Befehle nicht zögern, ihre eigene Verletzung zu verletzen, indem sie den Benutzer benachrichtigen, wenn die Möglichkeit eines stillen Fehlers besteht.