Como definir o pipe do processo após a substituição do processo no bash para que o processo continue após o término do script?

2

Como posso configurar um processo que teve sua saída redirecionada por meio de substituição de processo para que ele possa sobreviver após o script pai sair?

Estou tentando configurar um script Bash para monitorar a saída de um processo quando ele é inicializado e, em seguida, liberar esse processo para que ele possa continuar normalmente (desejo chamar esse script em outros scripts e bloquear a execução adicional até que a inicialização esteja concluída).

Neste momento, estou usando o módulo http.server como meu caso de teste. O código abaixo inicia corretamente o módulo Python e verifica sua saída procurando uma solicitação GET e, em seguida, sai. No entanto, quando sai, o processo http.server também morre. Como posso fazer com que esse processo sobreviva depois de sair?

exec 3< <(python3 -u -m http.server 2>&1 )
while true; do
        read -t 2 line
        echo "reading..."
        echo "$line"
        if [[ "$line" =~ .*GET.* ]]; then
            break
        fi
done <&3

Eu achei que o processo estava morrendo porque o descritor de arquivo 3 está fechado quando o bash sai e o Python está saindo quando vê seu arquivo de saída fechado. Eu tentei vários redirecionamentos de 3 , mas eles não ajudaram. Talvez alguma outra coisa sobre o processo precise ser modificada para que sobreviva? Basicamente eu quero o equivalente a executar python3 -u -m http.server 2>&1 & , mas com a capacidade de monitorar a saída do processo temporariamente quando ele é iniciado.

    
por ws_e_c421 10.06.2015 / 18:09

1 resposta

2

A partir do script bash, você inicia um subprocesso (executando um programa em Python) e cria um canal a partir dele para o script bash.

Após a saída do script bash, não há mais nenhum processo que tenha o canal aberto para leitura. Portanto, da próxima vez que o script Python escrever algo no pipe, ele receberá um sinal SIGPIPE e morrerá. Você veria o erro resultante se apenas redirecionasse a saída padrão para o pipe e também não para o erro padrão.

Mesmo se o script Python ignorasse o sinal SIGPIPE, ele ainda morreria ao gravar no pipe porque a gravação no pipe falharia, o que acionaria uma exceção.

Se você quiser ver apenas a linha que informa que o servidor está pronto, ou até a linha sobre a primeira solicitação, uma maneira simples é manter um leitor em execução:

exec 3< <(python3 -u -m http.server 2>&1 )
{ while true; do
  …
  done;
  exec cat;
} <&3

Você pode querer redirecionar o erro padrão para um arquivo de log em algum lugar, em vez de ignorar alegremente as mensagens de erro.

Uma abordagem alternativa seria escrever algumas linhas do Python, sobrescrevendo o método BaseHTTPRequestHandler.log_request para emitir uma entrada de log apenas na primeira vez.

    
por 11.06.2015 / 00:54