3> & 1 implica 4> & 3 5> & 3 ecc.?


31

Mi aspetterei

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

fallire con errori come / proc / self / fd / 4: nessun file o directory ecc., ma con mia sorpresa, viene emesso

foo
foo
foo
foo
foo

È come se 3>&1tutti i seguenti descrittori venissero reindirizzati su stdout, tranne che non funziona se cambio 3ad altro, come

$ 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

C'è una spiegazione per questo comportamento?

Risposte:


31

strace mostra questa sequenza di chiamate di sistema:

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

La prima riga si apre /proc/self/fd/3e le assegna il successivo numero fd disponibile, 4. /proc/self/fd/3è un percorso speciale. L'apertura ha un effetto simile al duping di fd 3: fd 4 punta nello stesso posto di fd 3, il tty.

La stessa cosa accade per ogni openat()chiamata successiva . Quando la polvere si deposita, fds 4, 5, 6 e 7 sono tutti duplicati di fd 3.

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

Si noti che il 3>&1reindirizzamento non è importante. L'importante è che stiamo chiedendo a T di aprirsi /proc/self/fd/Ndove N è già in uso. Dovremmo ottenere lo stesso risultato se ci sbarazziamo di 3>&1e iniziamo /proc/self/fd/2invece a iniziare . Vediamo:

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

Confermato! Stesso risultato

Possiamo anche ripetere lo stesso numero fd più volte. Otteniamo lo stesso risultato quando premiamo fd 6. Quando raggiunge l'ultimo ha aperto abbastanza descrittori per rendere possibile il salto a 6.

$ echo foo | tee /proc/self/fd/{2,2,2,2,6}
foo
foo
foo
foo
foo
foo
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.