Wie ist dieser Befehl legal? "> Datei1 <datei2 katze"


61

Vorausgesetzt file2, der Befehl existiert bereits

> file1 < file2 cat

erscheint der Inhalt kopiert werden file2zu file1.

Aber ich kann diese Struktur nicht verstehen.

Ich verstehe, dass "Nothing" file1angesprochen wird (Erstellen oder Löschen seines Inhalts). Dann wird auf den Inhalt von file2verwiesen file1.

Warum ist catnach file2? Woher weiß es, cat file2ob die Operanden nicht in der richtigen Reihenfolge sind?


11
Welche "richtige Reihenfolge"? Können Sie einen Link zu einer Ressource / Lernmaterial bereitstellen, in der eine "richtige Reihenfolge" beschrieben ist?
Leichtigkeit Rennen mit Monica

7
Wenn Sie Fragen wie diese stellen, müssen Sie die Shell angeben. Unterschiedliche haben unterschiedliche Randfälle, insbesondere in Bezug auf die Umleitung.
chrylis -on strike-

Antworten:


117

Bevor die Shell den catBefehl in der Befehlszeile ausführt , sucht sie nach Umleitungen.

Es gibt zwei Weiterleitungen:

  1. >file1 Dadurch wird die Standardausgabe des Befehls auf "" gesetzt file1.
  2. <file2 Dies bewirkt, dass die Standardeingabe des Befehls von kommt file2.

Die Tatsache, dass diese Umleitungen an einem nicht funktionierenden Ort in der Befehlszeile platziert werden, spielt keine Rolle.

$ cat <file2 >file1

ist das gleiche wie

$ <file2 cat >file1

das ist das gleiche wie

$ <file2 >file1 cat

etc.¹

Beachten Sie, dass das catDienstprogramm in all diesen Fällen ohne Befehlszeilenargumente ausgeführt wird . Die Umleitungen sind keine Operanden des catBefehls, sondern Anweisungen an die Shell, um Umleitungen in und aus dem Befehl einzurichten (wobei die Standardeingabe und -ausgabe mit Dateien verbunden werden). Die Shell richtet die Umleitungen vor dem Aufrufen des Befehls ein.

Der Unterschied zwischen cat fileund cat <file(oder, wenn Sie so wollen <file cat) besteht darin, dass im ersten Fall das catDienstprogramm selbst die Datei, die als Operand in der Befehlszeile angegeben ist, zum Lesen öffnet, während im zweiten Fall die Shell dies tut öffne die Datei und verbinde catden Eingabestream mit it². Im zweiten Fall catwird festgestellt, dass ihm kein Dateioperand zugewiesen wurde, und automatisch von der Standardeingabe zum Lesen gewechselt. Dies ist eine Funktion von catund einiger anderer Dienstprogramme, die nicht alle Dienstprogramme ausführen.

catliest auch von seiner Standardeingabe, wenn er den Operanden hat -. Auch dies ist nur für catund für einige andere Dienstprogramme (dh nichts, was die Shell tut) etwas Besonderes . Zur Verwendung catim aktuellen Verzeichnis auf einer Datei , deren Name ist - , fügen Sie einen Pfad zu dem Dateinamen, wie zum Beispiel ./-.

¹ Die Reihenfolge der Weiterleitungen ist unter Umständen immer noch wichtig. With cat <file2 >file1wird beispielsweise file1nicht abgeschnitten, wenn kein Zugriff möglich file2ist (die Umleitungen werden von links nach rechts analysiert). Die relative Platzierung des Wortes catist jedoch noch willkürlich und wird dies nicht beeinflussen.

² Siehe auch die Frage " cat gibt beim Öffnen einer nicht vorhandenen Datei einen anderen Fehler aus ".


Die Tatsache, dass die Shell die Umleitungen einrichtet, bevor sie den Befehl in der Befehlszeile ausführt, ist der Grund, warum solche Dinge fehlschlagen und Sie eine leere Ausgabedatei erhalten:

$ sort file >file

Hier schneidet die Shell die Datei ab (leert sie), filebevor sie sort filedie sortStandardausgabe der Datei ausführt und mit der Datei verbindet. Das sortDienstprogramm öffnet fileund sortiert dann seinen Inhalt (der nichts ist). Das Ergebnis (nichts) wird über den Standardausgabestream an übergeben file.

Das Mittel in diesem speziellen Fall (zum Sortieren einer Datei "an Ort und Stelle") ist

$ sort -o file file

oder

$ sort file >file.sorted && mv file.sorted file

Das ist mehr oder weniger das, was sortpassiert, wenn die -oDatei zur Angabe des Namens der Ausgabedatei verwendet wird.


Nur um die Aussage zu sichern, dass die Umleitungen möglicherweise vor dem tatsächlichen Namen des Dienstprogramms in der Befehlszeile stehen:

Ein "einfacher Befehl" ist eine Folge von optionalen Variablenzuweisungen und -umleitungen in beliebiger Reihenfolge, optional gefolgt von Wörtern und Umleitungen, die von einem Steueroperator beendet werden. [Ref: POSIX Shell Command Language 2.9.1 Einfache Befehle]

Und auch darüber, dass die Umleitung nicht zu den Operanden des Dienstprogramms gehört:

Die optionale Zahl, der Umleitungsoperator und das Wort dürfen in den Argumenten für den auszuführenden Befehl (falls vorhanden) nicht enthalten sein. [Ref: POSIX Shell Command Language 2.7-Umleitung]


14
@Steve Die Freiheit, Umleitungen zu verschieben, kann verwendet werden, um einige Befehle klarer darzustellen, wie eine Pipeline mit einer Eingabeumleitung am Anfang <in foo | bar >outalles in logische Reihenfolge bringt. Ich bin auch gern echo >&2 Something bad happenedfür die Fehlerausgabe von Shell-Skripten. Aber >out <in catist nur Verschleierung

2
Wie könnte sort file >filerichtig durchgeführt werden?
Seth10

11
@setht Mit sort -o file file.
Kusalananda

6
Gute Antwort. Beachten Sie, dass die Reihenfolge wichtig ist. < file1 > file2 catwäre besser als, > file2 < file1 catda dies vermeiden würde file2, abgeschnitten zu werden, wenn file1es nicht geöffnet werden kann.
Stéphane Chazelas

3
Beachten Sie Folgendes : Wenn Sie mit HTML-Fragmenten auf POSIX verlinken, ist es besser, die genaue Ausgabe anzugeben (wie pubs.opengroup.org/onlinepubs/9699919799.2016edition ), da bekannt ist, dass sich Fragmente zwischen den Ausgaben derselben Version der Spezifikation ändern (Viele Links in Antworten auf dieser Website, einschließlich meiner, sind jetzt falsch, da die Fragmente nach der Veröffentlichung der Ausgabe 2016 an der falschen Stelle stehen.)
Stéphane Chazelas
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.