Por que esses dois comandos 'cat' resultam de forma diferente?

12

Vamos supor que o arquivo contenha um texto específico e eu execute o seguinte conjunto de comandos:

exec 3<infile

cat -n <&3

cat -n <&3

A primeira instância do cat exibirá o conteúdo do arquivo, mas a segunda vez não parece estar fazendo nada. Por que eles diferem?

    
por nonterrorist 10.12.2012 / 19:19

2 respostas

29

Eles se parecem com o mesmo comando, mas a razão pela qual eles diferem é que o estado do sistema foi alterado como resultado do primeiro comando. Especificamente, o primeiro cat consumiu o arquivo inteiro, portanto, o segundo cat não tem mais nada para ler, atinge o EOF (fim do arquivo) imediatamente e sai.

O motivo por trás disso é que você está usando exatamente a mesma descrição de arquivo (aquela que você criou com exec < infile e atribuída ao descritor de arquivo 3 ) para ambas as invocações de cat . Uma das coisas associadas a uma descrição de arquivo aberto é um deslocamento de arquivo. Então, o primeiro cat lê o arquivo inteiro, deixa o offset no final, e o segundo tenta pegar do final do arquivo e não encontra nada para ler.

    
por 10.12.2012 / 19:28
11

Apenas para adicionar à resposta do @jw013, pode ajudar a perceber que é o mesmo que

{
   cat -n
   cat -n
} < infile

< file sendo curto para 0< file , isto é, use o descritor de arquivo 0 em vez de 3.

E só para confundir um pouco o assunto, esta versão:

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

Comporta-se de forma diferente dependendo do SO em que você o executa e do tipo de infile (arquivo regular vs pipe vs device ...)

No Solaris e na maioria dos Unices comerciais, um open("/dev/fd/3") é mais ou menos equivalente a um dup(3) (portanto, < /dev/fd/3 é quase o mesmo que <&3 ), enquanto no Linux, para arquivos regulares, /dev/fd/3 é implementado como um link simbólico para o arquivo original, então open("/dev/fd/3") o abre novamente desde o início (e possivelmente com flags diferentes do fd 3).

    
por 10.12.2012 / 23:49