Pourquoi est-ce que ces deux commandes "cat" résultent différemment?

12

Supposons que infile contient un texte spécifique, et je devais exécuter l'ensemble de commandes suivant:

exec 3<infile

chat -n <&3

chat -n <&3

La première instance de cat affichera le contenu du fichier, mais la deuxième fois ne semble rien faire. Pourquoi diffèrent-ils?

non terroriste
la source

Réponses:

29

Ils ressemblent à la même commande, mais la raison pour laquelle ils diffèrent est que l'état du système a changé à la suite de la première commande. Plus précisément, le premier a catconsommé l'intégralité du fichier, de sorte que le second catn'a plus rien à lire, frappe immédiatement EOF (fin de fichier) et quitte.

La raison derrière cela est que vous utilisez exactement la même description de fichier (celle que vous avez créée avec exec < infileet attribuée au descripteur de fichier 3) pour les deux appels de cat. L'une des choses associées à une description de fichier ouvert est un décalage de fichier. Ainsi, le premier catlit l'intégralité du fichier, laisse le décalage à la fin, et le second essaie de reprendre à la fin du fichier et ne trouve rien à lire.

jw013
la source
12

Juste pour ajouter à la bonne réponse de @ jw013, il peut être utile de réaliser que c'est la même chose que

{
   cat -n
   cat -n
} < infile

< fileétant abrégé 0< file, c'est utiliser le descripteur de fichier 0 au lieu de 3.

Et juste pour confondre un peu la question, cette version:

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

Se comporte différemment selon le système d'exploitation dans lequel vous l'exécutez et le type de infile(fichier normal vs tuyau vs appareil ...)

Sur Solaris et la plupart des Unices commerciaux, un open("/dev/fd/3")est plus ou moins équivalent à un dup(3)(donc < /dev/fd/3est à peu près le même que <&3), tandis que sur Linux, pour les fichiers normaux, /dev/fd/3est implémenté en tant que lien symbolique vers le fichier d'origine, donc l' open("/dev/fd/3")ouvre à nouveau dès le début ( et éventuellement avec des drapeaux différents du fd 3).

Stéphane Chazelas
la source