Eu tento entender esse conceito há anos, com um conhecimento incompleto neste momento.
Alguém aqui pode fazer uma espécie de tutorial ou boas explicações com exemplos de como
- abrir um novo
fd
- ler de
fd
- usar
fd
- fechar
fd
Eu li https://www.gnu.org/software/bash/manual/html_node/Redirections.html e man bash
, mas não está claro, não há nenhum exemplo concreto e compreensível.
Se alguém puder explicar bem, será uma resposta valiosa, não só para mim. A sintaxe é na maioria das vezes um pouco ofuscada.
Às vezes isso requer exec
, às vezes não.
Algumas traduções para conchas do tipo Bourne:
open("file", O_RDONLY)
exec 3< file
open("file", O_RDONLY)
exec {fd}< file
$fd
²open("file", O_WRONLY|O_TRUNC|O_CREAT)
exec 3> file
open("file", O_WRONLY|O_APPEND|O_CREAT)
exec 3>> file
open("file", O_RDWR|O_CREAT)
exec 3<> file
open("file", ...)
sysopen ...
dup2(4, 5)
exec 5>&4
exec 5<&4
dup(4)
exec {fd}>&4
$fd
write(4, data, length)
print -rnu4 -- "$data"
print
também 5write(...)
syswrite ...
read(4, var...)
sysread -i 4 ... var
zsh/system
móduloread(4, var...)
IFS= read -ru4 ... var
close(4)
exec 4>&-
exec 4<&-
lseek(4, 123, SEEK_SET)
exec 4>#((123))
lseek(4, 123, SEEK_CUR)
exec 4>#((CUR + 123))
lseek(4, 123, SEEK_END)
exec 4>#((EOF + 123))
lseek(...)
sysseek ...
pipe()
exec 4>>|5
fstat(4, var)
zstat -f 4 -H var
select(...)
zselect ...
zsh também possui alguns módulos
zsh/net/socket
,zsh/net/tcp
,zsh/zpty
para criar e manipular outros tipos de fds.Usar
exec
altera os descritores de arquivo do processo shell. Na maioria das vezes, no entanto, você só deseja alterar os descritores de arquivo de algum outro comando, comols -l dir/ > file
(abreviação dels -l dir/ 1> file
) para abrirfile
em fd 1 (stdout)ls
apenas ou uma seção de código:foo | bar
faz umpipe()
7 seguido de algumdup2()
s ou equivalente eclose()
s em processos simultâneos, então fd 1 do processo que será executadofoo
vai para o final de escrita do pipe e fd 0 oubar
vai para o final de leitura. Outras construções de shell que usam ou podem usar pipes incluem substituição de comando (var=$(cmd)
,var=`cmd`
), substituição de processo de shell semelhante a Korn (foo <(bar) >(baz)
), coprocessos, redirecionamento de processo de yash.¹ em ksh93 e bash, se
file
for/dev/tcp|udp/host/port
, não faz uma abertura real, mas cria um soquete de rede.² O mesmo pode ser feito para os outros operadores
>
,>>
,<>
,>
³ Se a
noclobber
opção estiver ativada, umO_EXCL
será adicionado se o destino for um arquivo normal, que pode ser ignorado com os operadores>|
ou>!
dependendo do shell4 No Bourne shell, não havia
O_APPEND
, mas o shell procurou até o fim depois de aberto5 Em outros shells, você sempre pode fazer
printf %s "$var" >&4
. Isso não grava em fd 4, mas grava em fd 1, após um temporáriodup2(4, 1)
que de fato atinge o mesmo objetivo. O mesmo paraIFS= read -r line <&4
.6 Veja também a
systell(fd)
função matemática para retornar a posição de um fd que é outra interface paralseek()
7 Exceto com ksh93 em alguns sistemas que usam
socketpair()
s em vez de pipes. O mesmo vale para outras construções que usam pipes.Em primeiro lugar, você não deve se limitar a scripts de shell. O conceito de descritores de arquivo vem do sistema operacional e C. Os livros didáticos de script de shell referem-se a descritores de arquivo, mas na verdade estão ocultos de você dentro do próprio interpretador de shell. Portanto, perguntas como "como abrir um novo fd no shell" realmente não fazem sentido, pois você não trabalha diretamente com descritores de arquivo no shell.
Para usar descritores de arquivo diretamente, você deve usar C. Todas as outras linguagens são construídas sobre bibliotecas e máquinas virtuais escritas em C. Portanto, se você estiver interessado neste tópico, precisará aprender C. E, por favor, não confunda com C++ - este também poderia ser usado para comunicação direta com o sistema operacional, mas tem muito "ajuda" que seria um obstáculo para a tarefa de entender o sistema operacional.
E, claro, você precisa ler livros didáticos sobre como o sistema operacional é organizado. O melhor livro para isso: Modern Operating Systems de Andrew Tanenbaum. Está disponível em qualquer livraria e biblioteca.