Existem várias questões que o utilizam para fazer coisas como vários canais de saída sem usar substituição de processo:
- Existe uma maneira de canalizar a saída de um programa para dois outros programas?
- Trocando stdout e stderr
- Quando você usaria um descritor de arquivo adicional?
É seguro usar apenas um número fixo de fd para isso? É possível que um programa já o esteja usando conforme descritoaquie sobrescrevemos algo importante ou lemos algo não relacionado?
Responder1
É possível que um programa já o esteja usando
Não. Veja, o redirecionamento de E/S ocorre antes de um programa ou script ser iniciado.
Normalmente, quando um programa ou script é iniciado, apenas os descritores padrão (0/entrada padrão, 1/saída padrão e 2/erro padrão) estão abertos. (Eles podem se referir a um terminal, dispositivo, arquivo ou até mesmo um soquete de rede; mas espera-se que estejam abertos. Em vez de "fechar" um, redirecionamos um descritor indesejado de/para /dev/null
, essencialmente "nowhere"/"nothing" .)
Os programas usam descritores por meio de syscalls, como open
os que usam um descritor gratuito. Ou seja, eles não pedem ao kernel para abrir um arquivo ou soquetepara um descritor específico, o kernel escolhe o descritor. Portanto, o único caso em que um programa usa um descritor adicional é quando se espera que ele já esteja aberto quando o programa for iniciado. Existem alguns daemons utilitários raros como este - além dos descritores padrão, eles esperam que se, por exemplo, o descritor 3 estiver aberto quando eles iniciarem, ele esteja conectado ao seu serviço de gerenciamento (ou algo similar).
Se um programa decidir usar um descritor embutido em código (e a única razão pela qual o faria, é porque ele bifurca e executa outro programa queesperaesse descritor seja aberto; como eu disse, isso é muito raro), o descritor já aberto é fechado quando o programa o substitui por qualquer coisa para a qual ele seja usado. (A propósito, o kernel fecha quando o programa indica que deseja usar um descritor específico usando, por exemplo, dup2()
em sistemas POSIXy; o processo não precisa se preocupar.)
Os scripts Shell (Bash e sh) usam números de descritores fixos, portanto é possível que um script use um descritor específico para fazer alguns redirecionamentos de entrada/saída. Porém, quando isso acontece, os redirecionamentos anteriores são simplesmente ignorados e não surtem efeito, pois os scripts assumem que o descritor foi fechado. (Se um descritor estiver aberto e o script usar esse descritor para algum material interno, o descritor original será fechado primeiro - pelo kernel e pelos motivos mencionados no parágrafo anterior - quando os scripts o redirecionarem. Para qualquer tipo de para ocorrer vazamento de dados, o script teria que ser especialmentetestese um descritor já estiver aberto, eevitarredirecionando-o.)
Observe também que as unidades ou canais de E/S Fortran não estão relacionados aos descritores, mesmo que ambos utilizem um número para identificação. Portanto, mesmo que um programa Fortran utilize a unidade 10, isso não significa que utilize o descritor 10.
É seguro usar apenas um número fixo de fd para isso?
Sim. POSIX diz que um programa pode ter pelo menos 20 descritores abertos, então qualquer número fixo entre 3 e 19 deve funcionar perfeitamente.
O ponto chave é documentá-lo bem, de preferência em um breve comentário no início do script (para scripts), ou no uso ( -h
ou --help
opção de linha de comando) e na página de manual (para programas).
Para scripts, você pode assumir que se surgir um conflito (e se surgir, será do tipo "o script não funciona porque o canal fecha assim que o programa é iniciado", conforme detalhado acima), os usuários podem alterar o número descritor fixo para melhor atender às suas necessidades. Portanto, sua tarefa como roteirista é planejar com antecedência e tornar isso mais fácil para quem vier depois. (Um comentário claro descrevendo sua intenção e o design geral é suficiente; não é necessário transformar o número do descritor em uma variável ou descrever cada pequena ação que o script realiza.)
Para programas, é uma boa ideia torná-los configuráveis em tempo de execução. Por exemplo, você poderia fazer com que seu programa/daemon usasse o descritor 3, se aberto, para protocolo de controle especial com uma interface gráfica de usuário; mas, usando alguma opção de linha de comando, como '-c 5', use o descritor nomeado (ou, com -c /dev/name
ou -c named-pipe
ou -c :socketpath
use o arquivo especificado, pipe nomeado ou soquete de domínio local). Dessa forma, os usuários podem solucionar facilmente quaisquer conflitos com scripts.