Então eu estou tendo um problema com um serviço BASH no Debian 7 que eu tenho trabalhado por um bom tempo e que aleatoriamente começou a ter problemas com seu fifo, ou assim parece. Ele é baseado no tipo de seu exemplo clássico de uso do fifo e funcionou bem durante meses, mas de repente, hoje, começou a me causar problemas. Parece que sempre que coisas assim acontecem, é sempre algo completamente diferente do que eu concluí originalmente, então vou apresentar o que eu tenho e talvez alguém possa apontar para mim a parte óbvia que eu não estou vendo.
Como eu disse, meu código para leitura / escrita de um pipe nomeado é meio padrão. Eu fiz uma versão fervida (linhas de 150ish) que eu pensei em apresentar mas, é claro, funcionou bem e eu não tenho idéia do porquê. Então aqui está a versão superconduzida para referência:
#--------------------------------Writer Script--------------------------------------#
#!/bin/bash
fifoIn=".../path/fifoIn"
#Read user input
IFS='' #Changed IFS so that spaces aren't trimmed from input
while true; do
read -e line
printf "%b\n" "$line" >&4
done 4>"$fifoIn"
exit 0
#--------------------------------Reader Script--------------------------------------#
#!/bin/bash
fifoIn=".../path/fifoIn"
LogFile=".../path/srvc.log"
[ -d ".../path" ] || mkdir -p ".../path"
[ -e "$fifoIn" ] || mkfifo "$fifoIn"
printf "%b\n" "Flushing input pipe" >> "$LogFile"
dd if="$fifoIn" iflag=nonblock of=/dev/null >/dev/null 2>&1
while true; do
if read -t 0.1 -a str; then
printf "\n%s\n" "<${str[*]}>"
case "${str[0]}" in
"foo")
printf '%b\n' "You said foo..."
;;
"bar")
printf '%b\n' "You said bar..."
;;
"")
;;
*)
printf "%b\n" "${str[*]}:"
printf "%b\n" "Uhhuh..."
;;
esac
fi
done <"$fifoIn" >> "$LogFile" 2>&1 3>"$fifoIn"
Então você pega 'script de leitura' e o executa como um daemon, então fale com ele por echo
ing ou printf
ing ou use o script writer para enviar mensagens para o pipe nomeado, fifoIn
. Isso funcionou muito bem desde o início, mas hoje ficou estranho.
Por algum motivo, começou a escolher quem poderia escrever (ou pelo menos parecia que poderia escrever) para o canal. Eu não vi nenhum erro, mas eu tentaria enviar texto para o pipe e nada aconteceria no lado do serviço. Eu tenho tarefas agendadas configuradas para gravar no pipe e elas não passariam por nenhum problema enquanto eu echo
ing de um terminal não receberia nada. Nem mesmo erros ou permissões negaram mensagens. As tarefas agendadas são configuradas para serem o mesmo usuário do meu terminal, então não acho que isso seja uma permissão.
Parece que toda vez que eu apaguei o fifo e reiniciei o serviço, eu consegui algumas mensagens inseridas pelo terminal normalmente, mas nem sempre, que pareciam bloquear ou parar de funcionar depois que uma mensagem originada pelo cron era enviado para o serviço. Eu não seria mais capaz de enviar mensagens através do pipe, mas as mensagens originadas no cron continuariam a passar muito bem!
Eu fiz algumas pesquisas e me deparei com o comando strace
. Eu tentei fazer algo como strace printf '%b\n' "foo" >> .../path/fifoIn
, peguei um monte de coisas de chamadas de sistema de diagnóstico que eu realmente não entendi, mas parece que tudo deu certo porque não havia nada como Hey! right here! something broke right here!!
e acabou com:
...
write(1, "foo\n", 4)
close(1)
...
que eu estou supondo é uma coisa boa. Agora, o mais engraçado, a mensagem passou e o daemon leu como esperado! Eu removi o strace
dessa linha exata e, novamente, sem dados.
Então, todos vocês que sabem muito mais sobre as operações e as chamadas do sistema do que eu, o que acontece de forma diferente quando você tem strace
como prefácio e quando não tem? O que geralmente pode escovar um tubo sem ter sido fechado para leitura? Quaisquer outros leads que você possa pegar porque eu estou perdido.
UPDATE
@Gilles, acho que você está fazendo algo sugerindo outros processos tentando ler o mesmo canal e causando problemas ... Eu escrevi uma nova função que chama algumas instâncias de mutt que parecem ter alguma associação com fifoIn
por algum motivo. Eu não estou muito certo de como ler a saída de lsof
, mas ele lê isso depois que eu executo essa função (e conseqüentemente estouro do meu cachimbo):
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
mutt 13874 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13874 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13897 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13897 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13932 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13932 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13971 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 13971 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14012 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14012 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14051 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14051 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14096 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14096 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14124 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
mutt 14124 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
srvc 14298 uname 0r FIFO 8,17 0t0 393222 .../path/fifoIn
srvc 14298 uname 3w FIFO 8,17 0t0 393222 .../path/fifoIn
lsof 15587 uname 1w FIFO 0,8 0t0 176516 pipe
lsof 15587 uname 5w FIFO 0,8 0t0 176524 pipe
lsof 15587 uname 6r FIFO 0,8 0t0 176525 pipe
grep 15588 uname 0r FIFO 0,8 0t0 176516 pipe
lsof 15589 uname 4r FIFO 0,8 0t0 176524 pipe
lsof 15589 uname 7w FIFO 0,8 0t0 176525 pipe
Eu estou supondo que eu tenha omitido as chamadas do mutt (que acabam sendo executadas em subshells), mas elas estão trancando no FD herdado por causa do que eu fiz de errado com o comando. Eu diria que essa é a resposta e eu vou tirar daqui! Se você postar uma 'resposta', eu ficaria feliz em selecioná-la!