Wie funktioniert die Umleitung in Symbolen in einer Sequenz?

7

Ich habe Datei1, Datei2, Datei3.


Datei1 enthält 1

Datei2 enthält 2

Datei3 enthält 3

Ich benutze Befehl

cat file1 > file2 > file3

Ergebnisse in:

Datei1 1

Datei2 (enthält nichts)

file3 1


Warum wird irgendetwas in dieser Richtung zerstört? Was sehe ich eigentlich nicht hinter den Kulissen?

(Randnotizen mit "Anhängen" >>sind noch seltsamer)

Keine Zeit
quelle
Schauen Sie sich Murus Antwort unten an, wenn Sie eine Antwort darauf wünschen, wie der Befehl auf einer niedrigeren Ebene tatsächlich funktioniert!
Keine Zeit

Antworten:

14

Umleitungen in Bourne / POSIX-Shells wie Bash , Dash, Ksh usw.

verarbeitet in der Reihenfolge, in der sie erscheinen, von links nach rechts

> x Öffnet und schneidet die Datei xund legt den Dateideskriptor fest, in den xals Standardausgabe geschrieben wird. Ihr Befehl:

cat file1 > file2 > file3

Wille:

  1. Öffnen und abschneiden file2
  2. Stellen Sie die Standardausgabe so ein, dass in diesen Dateideskriptor geschrieben wird
  3. Öffnen und abschneiden file3
  4. Stellen Sie die Standardausgabe so ein, dass in diesen Dateideskriptor geschrieben wird
  5. Lauf cat file1

Das Endergebnis ist, dass die Standardausgabe file3zu der Zeit ausgeführt wird cat. Beide file2und file3haben ihren aktuellen Inhalt gelöscht und erhalten file3die Ausgabe von cat(den Inhalten von file1) in sie geschrieben.


Wenn Sie die Ausgabe in mehrere Streams aufteilen möchten, die in separate Dateien geschrieben wurden, können Sie Folgendes verwendentee :

cat file1 | tee file2 > file3

Andere Shells verhalten sich ( insbesonderezsh ) anders, und Ihr Befehl würde das Ergebnis haben, das Sie wahrscheinlich erwartet haben: beides file2und file3den Inhalt von file1.


Beachten Sie, dass catdies hier nicht erforderlich ist. <Die Eingabeumleitung würde den Job genauso gut erledigen.

Michael Homer
quelle
Ich wünschte, ich könnte sowohl Ihre Antwort als auch @muru akzeptieren, da zsh es so macht, wie ich es ursprünglich erwartet hatte.
Keine Zeit
Während catnicht notwendig sein, einige ist Befehl, der aus der Eingabedatei liest. < inputfile > outputfileschneidet nur die Ausgabedatei ab, kopiert die Eingabedatei nicht in sie.
Barmar
Es ist eine präventive UUOC- Abteilung für das teeKommando. < x > yfunktioniert aber tatsächlich in zsh.
Michael Homer
Ich erinnere mich an Alta Vista. . (Link enthält Verweis auf alta vista) Es scheint fast so, als würde hier eine Formel funktionieren, um die Interaktion zu erklären, so wie es sein muss, muss jeder andere > or <entgegengesetzt sein, um den Datenfluss aufrechtzuerhalten. Aber ich weiß es wirklich nicht genau und bin zu müde, um nachzudenken.
Keine Zeit
9

Wenn Sie einen fd mehrmals umleiten, werden alle Umleitungen ausgeführt, und die letzte bleibt bestehen:

$ strace -f -e open bash -c 'cat file1 > file2 > file3'
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
...
[pid 20508] open("file2", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
[pid 20508] open("file3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 3
...
[pid 20508] open("file1", O_RDONLY)     = 3

Also file2wurde geöffnet und abgeschnitten und dann file3geöffnet.

muru
quelle
Das führt den Befehl also tatsächlich so durch, wie es durch c?
Keine Zeit
@NoTime Wenn Sie von strace sprechen, wird der Befehl wie gewohnt ausgeführt, es werden jedoch die durchgeführten Systemaufrufe aufgelistet. Diese können in jeder Sprache erstellt werden, in der die System-API verfügbar ist. Strace ist in dieser Hinsicht wie ein Debugger.
Muru
Das ist großartig, das hätte meine Frage wahrscheinlich mehr oder weniger genau dort beantwortet. Im Grunde ist es so, als würde man eine Variable 200 Mal setzen. Es ist wirklich egal, was die ersten 199 waren. (Nur ich versuche, Analogie für mich selbst zu machen)
Keine Zeit
@ NoTime ja, so sehe ich es auch. Und deshalb scheint mir das Verhalten von zsh, obwohl es sicherlich nützlicher ist, nicht intuitiv zu sein.
Muru
Ich finde deine Antwort großartig. Ich bin mir nicht sicher, ob es für so viele Menschen nützlich sein wird (es war sehr effektiv für mich), also habe ich es nicht akzeptiert (sorry). Aber ich habe eine Ihrer anderen großen Fragen positiv bewertet.
Keine Zeit