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