O que significa o script a seguir?
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?
Responder1
Ele redireciona stdin (FD0) para FD4, redireciona de /etc/XX/cfg
para FD0, lê uma linha de FD0 e então move FD4 de volta para FD0. Resumindo, ele salva, substitui e restaura stdin, enquanto lê uma linha de um arquivo intermediário.
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 mostrado.
Responder2
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);
Responder3
A maneira como li isso - com base na seção da página de manual do bash em REDIRECTION - é que stdin
(fd0) é redirecionado para fd4, então a entrada é obtida de /etc/XX/cfg
into stdin
- que terminará em fd4.
read line1
deve então pegar de fd4 que é então colocado de volta em fd0.
Uma demonstração pode mostrar um pouco melhor o que quero dizer 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 a configuração por redirecionamento, portanto, no código acima, extraí valores de "config" (suposição de minha parte com base no nome do arquivo - ruim :)), mas eu também pode processar via stdin.
por exemplo:
$ ./test.sh < somefile
$ cat somefile | ./test.sh
Espero que isso explique tudo.