Reiniciar o programa em execução em segundo plano e ainda fazê-lo consumir do stdin

Reiniciar o programa em execução em segundo plano e ainda fazê-lo consumir do stdin

Esta é uma extensão da pergunta anterior que eu fizaqui

{
 python2 readLines.py &
 python2 readLines.py &
 python2 readLines.py &
 python2 readLines.py &
 python2 readLines.py &
} | tee  output_file | java program 

Tenho usado o script com sucesso para servir ao meu propósito (pode não estar correto de acordo com os princípios de programação)

Estou executando o script da seguinte maneira

./script.sh &

Pergunta

Existe alguma maneira de reiniciar apenas a parte do programa Java da configuração acima?

Tentativas

  • Assim que o script programfor interrompido, todo o script será desativado.
  • Tentei um programa simples em python lendo stdine imprimindo os dados. Executado em uma janela de tmuxsessão. Tentei escrever stdoutde outra janela da sessão no mesmo prompt de comando do host, que não funcionou (provando que preciso ler mais sobre stdincomo tal). Isso foi para ver se a gravação dos dados no arquivo + stdoute a leitura stdinpodem ser separadas, se houver.

Responder1

Provavelmente não; reiniciar o consumidor de insumo padrão requer a capacidade desse consumidor para execsi mesmo.

#include <err.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    char buf[1];
    int ret;
    int linenumber = 0;
    fprintf(stderr, "collect me some input...\n");
    while (1) {
        ret = read(STDIN_FILENO, buf, 1);       // unbuffered. inefficient
        if (ret == 0)           // EOF
            exit(EXIT_SUCCESS);
        else if (ret < 0)
            err(1, "read failed");

        write(STDOUT_FILENO, buf, 1);

        if (buf[0] == '\n') {
            linenumber++;
            if (linenumber == 4) {      // restart ourself every four lines...
                execvp(*argv, argv);
                err(1, "exec failed");
            }
        }
    }
    exit(EXIT_SUCCESS);
}

Que quando executado se reinicia a cada quatro linhas:

$ make execself
cc     execself.c   -o execself
$ perl -E 'say "line $_" for 1..8' | ./execself
collect me some input...
line 1
line 2
line 3
line 4
collect me some input...
line 5
line 6
line 7
line 8
collect me some input...
$ 

Vou arriscar e adivinhar que uma tomada oufila de mensagenspode atender melhor à necessidade de encerrar e reiniciar aleatoriamente o consumidor de saída, pois então as mensagens permaneceriam (até um limite de buffer ou com bloqueio ...) enquanto o processo do consumidor está sendo eliminado e reiniciado. Ou você pode escrever algum tipo de proxy que leia a entrada padrão e seja tolerante com o fato de o consumidor Java subsequente não estar disponível aleatoriamente, ou ser capaz de reiniciar o referido consumidor com mais ou menos facilidade.

(Observe que, com leituras em buffer, o consumidor pode precisar de esforços adicionais para processar ou de alguma forma repassar quaisquer dados incompletos que foram lidos pela leitura em buffer, mas que não foram tratados no momento da reinicialização ou saída...)

informação relacionada