Eu estava tentando usar a substituição de processos e me deparei com o seguinte exemplo:
exec 3>&1
tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&- | bzip2 -c > file.tar.bz2 3>&-
exec 3>&-
Pelo que entendi, isso significa o seguinte:
Crie um descritor de arquivo
3
e anexe-o a stdout.tar
compactará os arquivos no diretório definido por$directory_name
e o arquivo compactado é denotado internamente pelo descritor de arquivo4
.O descritor de arquivo
4
está anexado a stdout.stdout é anexado ao descritor de arquivo
3
e o descritor de arquivo é3
fechado.
Mas, novamente, bzip2
o descritor de arquivo é fechado novamente e, na linha final, o exec
comando também está fechando o descritor 3
. Aí estou perdido, por que o mesmo descritor de arquivo é fechado 3 vezes?
Estes são descritores diferentes. Veja esta boa resposta . Diz:
Em um caso como
tar cf /dev/fd/4 $directory_name 4>&1 >&3 3>&-
os redirecionamentos são tratados pelo shell antestar
mesmo de começar, mas o princípio é o mesmo: esses descritores não são os do shell principal. Quandotar
inicia (estritamente: quando a cópia do shell eventualmente executa paratar
), seus/dev/fd/*
links já estão preparados e não há/dev/fd/3
.Da mesma forma
bzip2
encontra seus próprios descritores preparados. Eles podem ser vinculados aos mesmos arquivos que os descritores de algum outro processo, mas são entidades separadas.Tenha em mente que cada processo vê seus próprios descritores em
/dev/fd/
, é um truque útil. Se você considerar/proc/<PID>/fd/
os diretórios, ficará mais claro que os descritores são por PID.Finalmente
exec 3>&-
fecha o descritor para o shell principal. É ainda outra entidade separada.