¿Por qué es que estos dos comandos 'cat' resultan de manera diferente?

12

Supongamos que el archivo contiene un texto específico, y que debía ejecutar el siguiente conjunto de comandos:

ejecutivo 3<infile

gato -n <&3

gato -n <&3

La primera instancia de cat mostrará el contenido del archivo, pero la segunda vez no parece estar haciendo nada. ¿Por qué difieren?

no terrorista
fuente

Respuestas:

29

Parecen el mismo comando, pero la razón por la que difieren es que el estado del sistema ha cambiado como resultado del primer comando. Específicamente, el primero catconsumió todo el archivo, por lo que al segundo catno le queda nada para leer, toca EOF (final del archivo) inmediatamente y sale.

La razón detrás de esto es que está utilizando exactamente la misma descripción de archivo (la que creó con exec < infiley se asignó al descriptor de archivo 3) para ambas invocaciones de cat. Una de las cosas asociadas con una descripción de archivo abierto es un desplazamiento de archivo. Entonces, el primero catlee todo el archivo, deja el desplazamiento al final, y el segundo intenta recogerlo desde el final del archivo y no encuentra nada para leer.

jw013
fuente
12

Solo para agregar a la buena respuesta de @ jw013, puede ser útil darse cuenta de que es lo mismo que

{
   cat -n
   cat -n
} < infile

< filepara abreviar 0< file, es decir, usar el descriptor de archivo 0 en lugar de 3.

Y solo para confundir un poco el asunto, esta versión:

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

Se comporta de manera diferente según el sistema operativo en el que lo ejecute y el tipo de infile(archivo normal vs tubería vs dispositivo ...)

En Solaris y en la mayoría de las unidades comerciales, un open("/dev/fd/3")es más o menos equivalente a un dup(3)(por lo que < /dev/fd/3es casi lo mismo que <&3), mientras que en Linux, para archivos normales, /dev/fd/3se implementa como un enlace simbólico al archivo original, por lo que se open("/dev/fd/3")abre de nuevo desde el principio ( y posiblemente con diferentes banderas del fd 3).

Stéphane Chazelas
fuente