Por que ler funciona se stdin for redirecionado para fd4?

4

O que significa o seguinte script?

exec 4<&0 0</etc/XX/cfg
read line1
exec 0<&4

Ele redireciona fd0 para fd4 e "/ etc / XX / cfg" para fd0.

Então, por que read ainda funciona, não deveria estar vazio?

    
por daisy 10.04.2012 / 12:33

3 respostas

5

Ele redireciona stdin (FD0) para FD4, redireciona de /etc/XX/cfg para FD0, lê uma linha de FD0 e, em seguida, move FD4 de volta para FD0. Em resumo, ele salva, substitui e restaura o stdin, enquanto lê uma linha de um arquivo entre eles.

read line1 < /etc/XX/cfg seria muito mais fácil, mas é impossível dizer se é uma substituição válida com base apenas no código exibido.

    
por 10.04.2012 / 12:43
3

Para reformular isso em syscalls (usando C):

exec 4<&0 0</etc/XX/cfg

/* Duplicate fd0 as fd4.  */
dup2 (0, 4);

/* Open file on fd0.
   "open" always uses lowest available descriptor, so we don't need to check it. */
close (0);
open ("/etc/XX/cfg", O_RDONLY);

exec 0<&4

/* Close fd0 and duplicate fd4 as fd0.  */
dup2 (4, 0);
    
por 10.04.2012 / 14:00
0

A forma como eu leio isso - com base na seção bash manpage do REDIRECTION - é que stdin (fd0) é redirecionado para fd4, então a entrada é tirada de /etc/XX/cfg para stdin - que terminará em fd4 .

read line1 deve então pegar fd4, que é então colocado de volta em fd0.

Uma demonstração pode mostrar meu significado um pouco melhor e responder "por que" você pode fazer isso. Adicionando outra linha e colocando-a em um wrapper:

$ vim ./test.sh
#!/bin/bash
exec 4<&0 0</etc/XX/cfg
read line1    # reads from fd4
exec 0<&4
read line2    # reads from fd0

echo $line1 
echo $line2

Você pode canalizar ou redirecionar stdin via test.sh mas também ler na configuração por redirecionamento, então no código acima eu obtive valores da "config" (suposição da minha parte baseada no nome do arquivo - ruim :)), mas também posso processar via stdin.

por exemplo:

$ ./test.sh < somefile
$ cat somefile | ./test.sh

Espero que isso explique isso.

    
por 10.04.2012 / 14:01