it-swarm.com.de

Wie ist dieser Befehl legal? "> Datei1 <Datei2 Katze"

Angenommen, file2 Existiert bereits, der Befehl

> file1 < file2 cat

scheint den Inhalt von file2 nach file1 zu kopieren.

Aber ich kann diese Struktur nicht verstehen.

Ich verstehe, dass "Nothing" an file1 Gerichtet wird (Erstellen oder Löschen seines Inhalts). Dann wird der Inhalt von file2 An file1 Gerichtet.

Warum steht cat nach file2? Woher weiß es cat file2, ob die Operanden nicht in der richtigen Reihenfolge sind?

61
shaqed

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

Es gibt zwei Weiterleitungen:

  1. >file1 Dadurch wechselt die Standardausgabe des Befehls zu file1.
  2. <file2 Dadurch kommt die Standardeingabe des Befehls von file2.

Die Tatsache, dass diese Umleitungen an einer wackeligen Stelle 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 Dienstprogramm cat in all diesen Instanzen ausgeführt wird - ohne Befehlszeilenargumente. Die Umleitungen sind keine Operanden für den Befehl cat, sondern Anweisungen an die Shell, um Umleitungen in den Befehl hinein und aus ihm heraus einzurichten (indem die Standardeingabe und -ausgabe mit Dateien verbunden wird). Die Shell richtet die Umleitungen vor ein und ruft den Befehl auf.

Der Unterschied zwischen cat file Und cat <file (Oder, wenn Sie so wollen, <file cat) Besteht darin, dass im ersten Fall das Dienstprogramm cat selbst die Datei öffnet , der als Operand in der Befehlszeile zum Lesen angegeben wird, während im zweiten Fall die Datei Shell die Datei öffnet und den Eingabestream von cat mit ihr verbindet². Im zweiten Fall bemerkt cat, dass ihm kein Dateioperand zugewiesen wurde, und wechselt automatisch zum Lesen von seiner Standardeingabe. Dies ist eine Funktion von cat und einiger anderer Dienstprogramme, die nicht alle Dienstprogramme ausführen.

cat liest auch von seiner Standardeingabe, wenn der Operand - angegeben ist. Dies ist wiederum nur für cat und einige andere Dienstprogramme (d. H. Nichts, was die Shell tut) etwas Besonderes. Um cat für eine Datei im aktuellen Verzeichnis zu verwenden, deren Name ist-, Fügen Sie dem Dateinamen einen Pfad hinzu, z. B. ./-.

¹ Die Reihenfolge der Weiterleitungen ist unter bestimmten Umständen immer noch wichtig. Bei cat <file2 >file1 Wird beispielsweise file1 Nicht abgeschnitten, wenn auf file2 Nicht zugegriffen werden kann (die Umleitungen werden von links nach rechts analysiert). Die relative Platzierung des Wortes cat ist jedoch immer noch willkürlich und hat keinen Einfluss darauf.

² 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 der Befehl in der Befehlszeile ausgeführt wird, ist der Grund, warum solche Dinge fehlschlagen und Sie eine leere Ausgabedatei erhalten:

$ sort file >file

Hier schneidet die Shell die Datei file ab (leer), bevor sie sort file Ausführt und die Standardausgabe von sort mit der Datei verbindet. Das Dienstprogramm sort öffnet dann file und sortiert seinen Inhalt (was nichts ist). Das Ergebnis (nichts) wird über den Standardausgabestream an file übergeben.

Die Abhilfe 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

dies ist mehr oder weniger das, was sort tut, wenn die Datei -o verwendet wird, um den Namen der Ausgabedatei anzugeben.


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

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

Und auch darüber, dass die Umleitung nicht Teil der Operanden des Dienstprogramms ist:

Die optionale Nummer, der Umleitungsoperator und Word dürfen nicht in den Argumenten für den auszuführenden Befehl enthalten sein (falls vorhanden). [ref: POSIX Shell Command Language 2.7 Redirection]

118
Kusalananda