Eu tenho um programa que sai automaticamente após a leitura de um EOF em um determinado fluxo (no caso a seguir, stdin).
Agora eu quero criar um script de shell, que crie um pipe nomeado e conecte o stdin do programa a ele. Em seguida, o script grava no canal várias vezes usando echo
e cat
(e outras ferramentas que geram automaticamente um EOF quando saem). O problema que estou enfrentando é que, quando o primeiro echo
é concluído, ele envia um EOF ao canal e faz com que o programa saia. Se eu usar algo como tail -f
, não posso enviar um EOF quando pretendo sair do programa. Estou pesquisando uma solução equilibrada, mas sem sucesso.
Eu já descobri como impedir EOFs e como enviar um EOF manualmente, mas não posso combiná-los. Existe alguma dica?
#!/bin/sh
mkfifo P
program < P & : # Run in background
# < P tail -n +1 -f | program
echo some stuff > P # Prevent EOF?
cat more_stuff.txt > P # Prevent EOF?
send_eof > P # How can I do this?
# fg
exec 3>P
causa está pendurada no bash, por quê?exec 2>P
, e você tiver o modo de rastreamento ativado (set -x
), no qual o bash gravará no canal, mas não há leitor, pois ele bloqueia a espera por algo para ler.exec 3>P
trava na minha máquina. Isso ocorre porque não há leitura de processoP
. Assim, a solução foi trocar linhasexec 3>P
eprogram < P &
(adicionando o e comercial para que o programa seja executado em segundo plano).Um canal recebe EOF quando o último gravador desaparece. Para evitar isso, verifique se há sempre um gravador (um processo que tenha o canal aberto para gravação, mas na verdade não escreve nada). Para enviar o EOF, faça esse escritor de reserva desaparecer.
fonte
Não há como o programa distinguir entre um EOF que significa "é hora de sair" e um EOF que significa "um escritor está pronto, mas pode haver mais informações de outra pessoa".
Se você tem a capacidade de modificar o comportamento do seu programa, faça a leitura em um loop infinito (uma iteração dura até o EOF) e envie a ele uma sequência de comandos específica que significa "hora de sair". Enviar essa string seria a tarefa do
send_eof
comando na sua pergunta.Outra opção:
ou
fonte