Duplicação de descritores de arquivos
Este parece ser um dos tópicos mais confusos para quem está explorando as possibilidades do shell, e há motivos de sobra para isso. Portanto, neste artigo, vamos tentar jogar um pouco de luz sobre a duplicação de descritores de arquivos. Contudo, se você não tem conhecimento dos conceitos básicos do redirecionamento, eu sugiro que leia e assista a essa aula do Curso Shell GNU.
No processo da duplicação de um descritor de arquivos, o dispositivo para o qual um descritor de arquivos X aponta é copiado para o descritor de arquivos Y.
Y>&X ou Y<&X
Dica: pode facilitar muito ler a notação
&X
como "para onde aponta X".
Para que isso funcione, o apontamento do descritor de arquivos X tem que estar previamente definido, o que se dá no processamento (da esquerda para a direita) dos operadores de redirecionamento padrão em um comando ou na predefinição de um descritor customizado.
Observe:
~ $ ls -l /proc/self/fd > arquivo 2>&1
Neste exemplo, o shell processou o redirecionamento de FD1 (stdout) para arquivo
e, em seguida, duplicou o apontamento de FD1 em FD2 (stderr). Isso quer dizer que tanto FD1 quanto FD2 redirecionarão seus fluxos de dados para arquivo
, o que podemos comprovar lendo o seu conteúdo:
~ $ cat arquivo
total 0
lr-x------ 1 blau blau 64 mar 14 08:30 3 -> /proc/285844/fd
lrwx------ 1 blau blau 64 mar 14 08:30 0 -> /dev/pts/0
l-wx------ 1 blau blau 64 mar 14 08:30 1 -> /home/blau/arquivo
l-wx------ 1 blau blau 64 mar 14 08:30 2 -> /home/blau/arquivo
Repare que os descritores 1 e 2 eram links simbólicos para /home/blau/arquivo
durante a execução do comando. Além disso, no Bash, nós temos o mesmo resultado com a notação &>
:
~ $ ls -l /proc/self/fd &> arquivo
~ $ cat arquivo
total 0
lr-x------ 1 blau blau 64 mar 14 08:47 3 -> /proc/286130/fd
lrwx------ 1 blau blau 64 mar 14 08:47 0 -> /dev/pts/0
l-wx------ 1 blau blau 64 mar 14 08:47 1 -> /home/blau/arquivo
l-wx------ 1 blau blau 64 mar 14 08:47 2 -> /home/blau/arquivo
Por outro lado, se o experimento fosse realizado com a ordem inversa dos operadores, o resultado seria:
~ $ ls -l /proc/self/fd 2>&1 > arquivo
~ $ cat arquivo
total 0
lr-x------ 1 blau blau 64 mar 14 08:43 3 -> /proc/286076/fd
lrwx------ 1 blau blau 64 mar 14 08:43 0 -> /dev/pts/0
l-wx------ 1 blau blau 64 mar 14 08:43 1 -> /home/blau/arquivo
lrwx------ 1 blau blau 64 mar 14 08:43 2 -> /dev/pts/0
Como os operadores são processados da esquerda para a direita, no momento em que FD1 foi duplicado em FD2, FD1 apontava para sdtout (a tela do terminal), tendo sido redirecionado para arquivo
apenas no momento seguinte.
Com descritores customizados, o apontamento do novo descritor está previamente definido para um arquivo, tornando indiferente a ordem:
~ $ exec 3> arquivo
~ $ ls -l /proc/self/fd 2>&3 >&3
~ $ cat arquivo
total 0
lr-x------ 1 blau blau 64 mar 14 08:55 4 -> /proc/286459/fd
lrwx------ 1 blau blau 64 mar 14 08:55 0 -> /dev/pts/0
l-wx------ 1 blau blau 64 mar 14 08:55 1 -> /home/blau/arquivo
l-wx------ 1 blau blau 64 mar 14 08:55 2 -> /home/blau/arquivo
l-wx------ 1 blau blau 64 mar 14 08:55 3 -> /home/blau/arquivo
Mas, observe o que escrevemos para utilizar o descritor customizado FD3:
`>&3`
Isso significa que a saída padrão (FD1) receberá uma cópia do apontamento de FD3, e foi exatamente isso que nós vimos no resultado do último comando: ou seja, houve uma duplicação do descritor de arquivos 3.
Espero que tenha ficado mais claro... 😉