Entendo que o descritor de arquivos (ou manipulador de arquivos) é uma técnica de E / S de arquivos nos sistemas Linux.
Sei também que cada processo possui três fluxos padrão (stdin, stdout e stderr) que são representados por arquivos com descritores de 0 a 3.
No entanto, percebo que todos os processos com os quais examinei lsof -p <pid>
têm um descritor de arquivo extra 255
com permissão de leitura.
Com essa resposta , aprendi que esse recurso é específico do shell Bash , mas tanto a resposta quanto a fonte referenciada não explicam realmente para que serve esse descritor de arquivo.
Minha pergunta:
- Para que é o descritor de arquivos 255?
- Posso usá-lo no meu script Bash ou é apenas um mecanismo de trabalho interno que não deve ser usado / manipulado manualmente?
bash
file-descriptors
Tran Triet
fonte
fonte
Respostas:
Para a última parte da sua pergunta:
posso usá-lo?
De
man bash
:Então, se você quer usar como criar um novo fd com esse número, a resposta é não.
Se você quer dizer usar como: "escreva para esse fd":
Ou para ler:
a resposta é sim.
Mas, provavelmente, deve ser melhor (independente do shell) usar
/dev/tty
para acessar otty
.para que serve o descritor de arquivo 255?
Como uma conexão alternativa ao tty no caso de fd 1 (
/dev/stdout
) e fd 0 (/dev/stdin
) serem bloqueados.Mais detalhes .
Outras conchas podem usar um número diferente (como 10 no zsh)
Da lista de e-mails :
fonte
dd bs=1 | bash -i -c 'sleep .1; ls -l /proc/$$/fd' 2>/tmp/err | tee /tmp/out
. Além disso, esse comentário da lista de discussão é sobre quandobash
é executado comobash scriptfile
(255
sendo nesse caso o identificador aberto parascriptfile
- e nesse caso,ls -l /proc/pid/fd
será impresso de forma muito convincente255 -> scriptfile
;-)), não sobre quando é executado interativamente./dev/tty
, e não do fd 0 ou fd 1 c) se os fds 0, 1 ou 2 forem "bloqueados", o bash não usará esses 255 fd como uma alternativa para lendo a entrada do usuário ou para escrever a saída do comando, avisos, mensagens de erro, etc.Esse
255
descritor de arquivo é um identificador aberto para o controle tty e é usado apenas quandobash
é executado no modo interativo.Ele permite que você redirecione o
stderr
no shell principal, enquanto ainda permite que o controle da tarefa funcione (por exemplo, seja capaz de matar processos com ^ C, interrompê-los com ^ Z, etc).Exemplo:
Se você tentar isso em um shell como o
ksh93
que está simplesmente usando o descritor de arquivo 2 como referência para o terminal de controle, osleep
processo ficará imune a ^ C e ^ Z e terá que ser eliminado de outra janela / sessão. Isso ocorre porque o shell não poderá definir o grupo de processossleep
como o primeiro plano no terminaltcsetgrp()
, pois o descritor de arquivo 2 não aponta mais para o terminal.Isso não é
bash
específico, também é usado emdash
ezsh
, apenas que o descritor não seja movido tão alto (geralmente é 10).zsh
também usará esse fd para fazer eco das solicitações e da entrada do usuário; portanto, simplesmente o seguinte funcionará:Não tem nada a ver com o que os manipuladores de arquivos
bash
estão usando ao ler scripts e configurar pipes (que também são desviados com a mesma função -move_to_high_fd()
), como foi sugerido em outras respostas e comentários.bash
está usando um número tão grande para permitir que fds maiores do9
que sejam usados com redirecionamentos no shell (por exemploexec 87<filename
); isso não é suportado em outras conchas.Você pode usar esse arquivo sozinho, mas há pouco sentido em fazê-lo, porque você pode obter um identificador para o mesmo terminal de controle em qualquer comando com
... < /dev/tty
.Análise do código fonte do bash :
Em
bash
, o descritor de arquivo do terminal de controle é armazenado nashell_tty
variável Se o shell for interativo, essa variável será inicializada (na inicialização ou após uma falha no exec)jobs.c:initialize_job_control()
, duplicando-astderr
(sestderr
estiver conectada a um terminal) ou abrindo diretamente/dev/tty
e, em seguida, duplicando novamente para um valor de fd mais alto comgeneral.c:move_to_high_fd()
:Se
shell_tty
ainda não é o tty de controle, é feito o seguinte:shell_tty
é então usado paraobter e definir o grupo processo em primeiro plano com
tc[sg]etpgrp
nojobs.c:maybe_give_terminal_to()
,jobs.c:set_job_control()
ejobs.c:give_terminal_to()
obter e definir os
termios(3)
parâmetrosjobs.c:get_tty_state()
ejobs.c:set_tty_state()
obtenha o tamanho da janela do terminal com
ioctl(TIOCGWINSZ)
inlib/sh/winsize.c:get_new_window_size()
.move_to_high_fd()
geralmente é usado com todos os descritores de arquivos temporários usados porbash
(arquivos de script, pipes, etc.), daí a confusão na maioria dos comentários que aparecem com destaque nas pesquisas do Google.Os descritores de arquivo usados internamente por
bash
, inclusive,shell_tty
estão todos configurados para fechar em execução, para que não sejam vazados para comandos.fonte