Posso simular o utilitário tee usando descritores de arquivos extras?

0

Eu ainda não me dei conta de como usar descritores de arquivos adicionais. Eu suspeito que você poderia usá-los para simular o que o utilitário tee faz, exibindo a saída de um comando enquanto simultaneamente o grava em um arquivo. Eu também suspeito que isso ajudaria a entender melhor como usar descritores de arquivos adicionais ...

Minhas tentativas até agora,

date 3>&1 3>file

Meu raciocínio era criar 3 como uma duplicata de 1 (stdout) e redirecionar 3 para gravar em file . ter stdout escrevendo no terminal como de costume, e 3 escrevendo em um arquivo.

Mas isso não funciona. Quando eu cat file , está vazio. Onde eu errei?

    
por ivan 01.07.2017 / 01:44

2 respostas

2

Um operador de redirecionamento muda para onde a saída está indo (ou de onde a entrada está vindo). 3>&1 significa “tornar descritor de arquivo 3 ponto onde quer que o descritor de arquivo 1 esteja atualmente apontando” (que é o terminal). 3>file significa "fazer o descritor de arquivo 3 apontar para file ". Nada aconteceu durante o breve tempo que o fd 3 estava apontando para o terminal, então você não obtém nenhuma saída de terminal.

Para obter os mesmos dados em dois locais, algo precisa copiar os dados. Esse é o trabalho de tee . Para cada byte que ele lê, ele gera esse byte duas vezes (se for fornecido um argumento de arquivo, mais sua saída padrão).

Não se atenha ao fato de que >& às vezes é chamado de duplicação. O que está duplicando é o descritor de arquivo : 3>&1 duplica fd 1 para fd 3, o que significa que os dados indo para fd 1 e os dados indo para fd 3 estão sendo mesclados - ambos estão indo para onde quer que fd 1 estivesse apontando.

Se você preferir explicações gráficas, consulte o que significa conectar STDOUT e STDIN? e Como um comando pode ter mais de uma saída?

Em qualquer caso, o seu comando não produz nada no descritor de arquivo 3, portanto redirecionar o fd 3 não altera nada. O comando date grava em sua saída padrão, ou seja, fd 1, e você não está redirecionando isso.

O Zsh tem um recurso chamado multios que altera o significado do redirecionamento de saída. Se houver vários redirecionamentos de saída para o mesmo comando no mesmo descritor de arquivo, então o primeiro muda onde o descritor está apontando, mas os subsequentes replicam os dados para o especificado alvos. Por exemplo, para obter saída em um arquivo além de onde stdout estava apontando, você pode usar

date >&1 >file

Zsh está fazendo o trabalho de tee . Observe que a ordem de redirecionamentos é importante - date >file >&1 escreveria em file duas vezes, pois, quando o operador >&1 for avaliado, a saída padrão de date já estará indo para file .

    
por 03.07.2017 / 00:19
1

Não, porque não duplica a saída. Para duplicar os descritores de arquivo, você também deve enviar para eles duas vezes.

Embora você possa fazer isso com um loop, assim:

while read l
do
   echo "$l" >&3
   echo "$l" >&4
done

Com dados binários, ele terá bugs (zeros serão desfeitos, crlf-s será convertido em lf).

Seu exemplo fez isso:

  1. aberto fd 3 para arquivar
  2. clonado fd 1 para no lugar de fd 3 (ou seja, ele fechou seu fd3 anterior e então fez o fd3 ser um "endereço alternativo" do seu stdout anterior) .

O redirecionamento é essencialmente um clone, na terminologia do unix, é como um link rígido. Com um sufixo 3>&1 para um commant, você terá fd 3 e fd 1 apontando para a mesma entidade (que agora é file ).

Se você tiver alguma afinidade com C, eu gostaria de verificar um man 3 dup2 , isso é exatamente o que um redirecionamento fd faz.

    
por 01.07.2017 / 01:49