Apakah 3> & 1 menyiratkan 4> & 3 5> & 3 dll?

31

Saya harapkan

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

gagal dengan kesalahan seperti / proc / self / fd / 4: Tidak ada file atau direktori dll, tetapi yang mengejutkan saya, ini menghasilkan

foo
foo
foo
foo
foo

Ini seperti 3>&1menyebabkan semua deskriptor berikut diarahkan ke stdout, kecuali itu tidak berfungsi jika saya mengubah 3ke yang lain, seperti

$ 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

Apakah ada penjelasan untuk perilaku ini?

oguz ismail
sumber

Jawaban:

31

strace menunjukkan urutan panggilan sistem ini:

$ 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
...

Baris pertama terbuka /proc/self/fd/3dan memberinya nomor fd 4. berikutnya yang tersedia, /proc/self/fd/3adalah jalur khusus. Membuka itu memiliki efek yang mirip dengan dup fd 3: fd 4 poin ke tempat yang sama dengan fd 3, tty.

Hal yang sama terjadi untuk setiap suksesi openat() panggilan . Ketika debu mengendap, fds 4, 5, 6, dan 7 semuanya merupakan duplikat dari fd 3.

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

Perhatikan bahwa 3>&1pengalihan tidak penting. Yang penting adalah kami meminta tee untuk membuka di /proc/self/fd/Nmana N sudah digunakan. Kita harus mendapatkan hasil yang sama jika kita menyingkirkan 3>&1dan memiliki tee mulai /proc/self/fd/2sebagai gantinya. Ayo lihat:

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

Dikonfirmasi! Hasil yang sama

Kami juga dapat mengulangi nomor fd yang sama berulang-ulang. Kami mendapatkan hasil yang sama ketika kami menekan fd 6. Pada saat mencapai yang terakhir ia telah membuka cukup deskriptor untuk memungkinkan lompatan ke 6.

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