Primeiro, observe que a sintaxe de fechamento é 5>&-
ou 6<&-
, dependendo se o descritor de arquivo está sendo lido para gravação ou para leitura. Parece haver um erro de digitação ou falha de formatação nesse post do blog.
Este é o script comentado.
exec 5>/tmp/foo # open /tmp/foo for writing, on fd 5
exec 6</tmp/bar # open /tmp/bar for reading, on fd 6
cat <&6 | # call cat, with its standard input connected to
# what is currently fd 6, i.e., /tmp/bar
while read a; do #
echo $a >&5 # write to fd 5, i.e., /tmp/foo
done #
Não há fechamento aqui. Como todas as entradas e saídas estão indo para o mesmo lugar neste exemplo simples, o uso de descritores de arquivos extras não é necessário. Você poderia escrever
cat </tmp/bar |
while read a; do
echo $a
done >/tmp/foo
O uso de descritores de arquivos explícitos se torna útil quando você deseja gravar em vários arquivos. Por exemplo, considere um script que envia dados para um arquivo de saída de dados e registra dados em um arquivo de log e, possivelmente, também em mensagens de erro. Isso significa três canais de saída: um para dados, um para logs e um para erros. Como existem apenas dois descritores padrão para a saída, um terceiro é necessário. Você pode chamar exec
para abrir os arquivos de saída:
exec >data-file
exec 3>log-file
echo "first line of data"
echo "this is a log line" >&3
…
if something_bad_happens; then echo error message >&2; fi
exec >&- # close the data output file
echo "output file closed" >&3
A observação sobre eficiência vem quando você tem um redirecionamento em um loop, como este (suponha que o arquivo esteja vazio para começar):
while …; do echo $a >>/tmp/bar; done
Em cada iteração, o programa abre /tmp/bar
, procura o final do arquivo, acrescenta alguns dados e fecha o arquivo. É mais eficiente abrir o arquivo de uma vez por todas:
while …; do echo $a; done >/tmp/bar
Quando há vários redirecionamentos acontecendo em momentos diferentes, é útil chamar exec
para executar redirecionamentos em vez de agrupar um bloco em um redirecionamento.
exec >/tmp/bar
while …; do echo $a; done
Você encontrará vários outros exemplos de redirecionamento navegando na tag io-redirection
neste site .