Perché questi due comandi "cat" risultano in modo diverso?


12

Supponiamo che infile contenga un testo specifico e che dovessi eseguire il seguente set di comandi:

exec 3<infile

cat -n <&3

cat -n <&3

La prima istanza di cat visualizzerà il contenuto del file, ma la seconda volta non sembra fare nulla. Perché differiscono?

Risposte:


29

Sembrano lo stesso comando ma il motivo per cui differiscono è lo stato del sistema è cambiato come risultato del primo comando. In particolare, il primo ha catconsumato l'intero file, quindi il secondo catnon ha più nulla da leggere, colpisce immediatamente EOF (fine del file) ed esce.

Il motivo alla base di questo è che stai usando la stessa identica descrizione del file (quella che hai creato exec < infilee assegnato al descrittore di file 3) per entrambe le invocazioni di cat. Una delle cose associate alla descrizione di un file aperto è un offset di file. Quindi, il primo catlegge l'intero file, lascia l'offset alla fine e il secondo tenta di riprendere dalla fine del file e non trova nulla da leggere.


12

Solo per aggiungere alla bella risposta di @ jw013, può essere utile rendersi conto che è la stessa

{
   cat -n
   cat -n
} < infile

< fileessendo l'abbreviazione di 0< file, ovvero utilizzare il descrittore di file 0 anziché 3.

E solo per confondere un po 'la questione, questa versione:

exec 3< infile
cat -n /dev/fd/3
cat -n /dev/fd/3

Si comporta in modo diverso a seconda del sistema operativo in cui lo si esegue e del tipo di infile(file normale vs pipe vs dispositivo ...)

Su Solaris e sulla maggior parte degli Unici commerciali, un open("/dev/fd/3")è più o meno equivalente a un dup(3)(quindi è più o meno < /dev/fd/3lo stesso di <&3), mentre su Linux, per i file regolari, /dev/fd/3è implementato come un collegamento simbolico al file originale, quindi lo open("/dev/fd/3")apre di nuovo dall'inizio ( e possibilmente con flag diversi da fd 3).

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.