Bedeutet 3> & 1 4> & 3 5> & 3 usw.?

31

Ich würde erwarten

echo foo | tee /proc/self/fd/{3..6} 3>&1

mit Fehlern wie / proc / self / fd / 4 zu scheitern: Keine solche Datei oder Verzeichnis usw., aber zu meiner Überraschung wird es ausgegeben

foo
foo
foo
foo
foo

Es ist so, als würden 3>&1alle folgenden Deskriptoren zu stdout umgeleitet, außer es funktioniert nicht, wenn ich 3zu etwas anderem wechsle , wie z

$ echo foo | tee /proc/self/fd/{3..6} 4>&1
tee: /proc/self/fd/3: No such file or directory
tee: /proc/self/fd/5: No such file or directory
tee: /proc/self/fd/6: No such file or directory
foo
foo
$ echo foo | tee /proc/self/fd/{4..6} 4>&1
tee: /proc/self/fd/5: No such file or directory
tee: /proc/self/fd/6: No such file or directory
foo
foo

Gibt es eine Erklärung für dieses Verhalten?

oguz ismail
quelle

Antworten:

31

strace zeigt diese Abfolge von Systemaufrufen:

$ strace -o strace.log tee /proc/self/fd/{3..6} 3>&1
...
$ cat strace.log
...
openat(AT_FDCWD, "/proc/self/fd/3", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 4
openat(AT_FDCWD, "/proc/self/fd/4", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 5
openat(AT_FDCWD, "/proc/self/fd/5", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 6
openat(AT_FDCWD, "/proc/self/fd/6", O_WRONLY|O_CREAT|O_TRUNC, 0666) = 7
...

Die erste Zeile wird geöffnet /proc/self/fd/3und weist ihr die nächste verfügbare FD-Nummer zu. 4. /proc/self/fd/3ist ein spezieller Pfad. Das Öffnen hat einen ähnlichen Effekt wie das Dupen von fd 3: fd 4 zeigt auf dieselbe Stelle wie fd 3, die tty.

Das gleiche passiert bei jedem aufeinanderfolgenden openat()Anruf. Wenn sich der Staub absetzt, sind fds 4, 5, 6 und 7 alle Duplikate von fd 3.

  • 1 → tty
  • 3 → tty
  • 4 → tty
  • 5 → tty
  • 6 → tty
  • 7 → tty

Beachten Sie, dass die 3>&1Umleitung nicht wichtig ist. Wichtig ist, dass wir das Tee bitten, dort zu öffnen, /proc/self/fd/Nwo N bereits verwendet wird. Wir sollten das gleiche Ergebnis erzielen, wenn wir loswerden 3>&1und /proc/self/fd/2stattdessen mit dem Abschlag beginnen . Wir werden sehen:

$ echo foo | tee /proc/self/fd/{2..6}
foo
foo
foo
foo
foo
foo

Bestätigt! Gleiches Ergebnis.

Wir können die gleiche fd-Nummer auch immer wieder wiederholen. Wir erhalten das gleiche Ergebnis, wenn wir fd 6 drücken. Bis es das letzte erreicht, hat es genügend Deskriptoren geöffnet, um den Sprung auf 6 zu ermöglichen.

$ echo foo | tee /proc/self/fd/{2,2,2,2,6}
foo
foo
foo
foo
foo
foo
John Kugelman
quelle