Primeiro, observe que a sintaxe para 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 formatação nessa postagem do blog.
Aqui está 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 local neste exemplo simples, o uso de descritores de arquivo 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 arquivo explícitos se torna útil quando você deseja gravar em vários arquivos por vez. Por exemplo, considere um script que produz dados para um arquivo de saída de dados e registre dados em um arquivo de log e, possivelmente, também mensagens de erro. Isso significa três canais de saída: um para dados, um para logs e outro para erros. Como existem apenas dois descritores padrão para saída, um terço é necessário. Você pode ligar 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 aparece 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
A cada iteração, o programa é aberto /tmp/bar
, procura o final do arquivo, anexa 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, a chamada exec
para executar redirecionamentos em vez de agrupar um bloco em um redirecionamento se torna útil.
exec >/tmp/bar
while …; do echo $a; done
Você encontrará vários outros exemplos de redirecionamento navegando na io-redirection
tag deste site .