Eu tenho um processo de servidor de longa execução dentro de uma sessão de tela no meu servidor Linux. É um pouco instável (e, infelizmente, não é o meu software, por isso não posso consertar isso!), Então quero criar um reinício noturno do processo para ajudar na estabilidade. A única maneira de fazer um desligamento normal é ir para o processo de tela, alternar para a janela em que está sendo executada e inserir a string "stop" em seu console de controle.
Existem contorções de redirecionamento inteligente que posso fazer para que um cronjob envie esse comando de parada em um horário fixo todos os dias?
ls -l /proc/7417/fd/0
./dev/pts/19
), oy
personagem não chega ao aplicativo em si. É semelhante ao que acontece quando você usa o comando write (1) . Enfim, tente minha outra resposta ou uma ferramenta de automação gráfica como o xdotool .Solução baseada em tela
Inicie o servidor assim:
a tela iniciará no modo desanexado; portanto, se você quiser ver o que está acontecendo, execute:
Controle o servidor assim:
(esta resposta é baseada no envio de entrada de texto para uma tela desanexada do site irmão do Unix e Linux )
Explicação dos parâmetros:
solução baseada em tmux
Inicie o servidor assim:
O tmux iniciará no modo desanexado, portanto, se você quiser ver o que está acontecendo, execute:
Controle o servidor assim:
Explicação dos parâmetros:
fonte
Tente isto para começar:
E isso para matar:
fonte
echo "xxx" > cmd
o programa será interrompido (porque o tubo será fechado). Embora alguns programas sejam inteligentes o suficiente para reabrirrewind(3)
seu stdin quando encontrarem EOF.É possível enviar texto de entrada para um processo em execução sem executar o
screen
utilitário ou qualquer outro utilitário sofisticado. E isso pode ser feito enviando esse texto de entrada para o "arquivo" de entrada padrão do processo/proc/PID#/fd/0
.No entanto, o texto de entrada precisa ser enviado de uma maneira especial para ser lido pelo processo. Enviar o texto de entrada através do
write
método de arquivo regular não fará com que o processo receba o texto. Isso ocorre porque isso será anexado apenas a esse "arquivo", mas não acionará o processo para ler os bytes.Para acionar o processo de leitura dos bytes, é necessário executar uma
IOCTL
operação do tipoTIOCSTI
para que cada byte seja enviado. Isso colocará o byte na fila de entrada padrão do processo.Isso é discutido aqui com alguns exemplos em C, Perl e Python:
https://unix.stackexchange.com/questions/48103/construct-a-command-by-putting-a-string-into-a-tty/48221
-
Portanto, para responder à pergunta original feita quase 9 anos atrás, o trabalho cron precisaria executar um pequeno script / programa utilitário semelhante aos exemplos que as pessoas escreveram para essa outra pergunta, que enviariam a string "stop \ n" para o processo do servidor em questão, através do envio de cada uma das 5 bytes através de uma
IOCTL
operação de tipoTIOCSTI
.Obviamente, isso funcionará apenas em sistemas que suportam o
TIOCSTI
IOCTL
tipo de operação (como Linux) e somente a partir daroot
conta do usuário, já que esses "arquivos"/proc/
são de "propriedade" delesroot
.fonte
Em caso de ajuda ninguém:
Eu tive um problema semelhante, e como o processo que eu estava usando não estava sob
screen
outmux
, eu tive que tomar uma abordagem diferente.Anexei
EDITARgdb
aoxterm
que meu processo estava sendo executado e useicall write(5, "stop\n", 5)
degdb
para escrever no descritor de arquivo mestre pty.Descobri para qual descritor de arquivo enviar os dados, procurando
/proc/<pid>/fd
um link/dev/ptmx
e, em seguida, tentativa e erro entre as duas opções (enviar minha string para os dois descritores de arquivo correspondentes parecia não causar nenhum dano).Aconteceu que o
EDIT FIMxterm
processo ao qual eu havia me conectado foi gerado com aspawn-new-terminal()
xterm
ação de uma combinação de teclas, e o segundoptmx
descritor de arquivo aberto foi simplesmente o processoptmx
paixterm
que não havia sido fechado.Portanto, as chamadas de tentativa e erro enviaram saída para esse outro terminal.
A maioria dos
xterm
processos não possui doisptmx
descritores de arquivo.Isso efetivamente digitou essa string no terminal e, portanto, a enviou para o processo em execução sob ele.
nb, talvez seja necessário permitir a conexão com um processo em execução com algo como
sudo bash -c "echo 0 > /proc/sys/kernel/yama/ptrace_scope"
fonte
Como não posso comentar a resposta mais aceita de Cristian Ciupitu (de 2010), tenho que colocar isso em uma resposta separada:
Esta questão já foi resolvida neste segmento: https://stackoverflow.com/questions/5374255/how-to-write-data-to-existing-processs-stdin-from-external-process
Em resumo:
Você deve iniciar seu processo com um canal para stdin que não bloqueia nem fecha quando a entrada atual foi gravada. Isso pode ser implementado por um loop infinito simples que será canalizado para o processo em questão:
Posso confirmar que isso é diferente da maneira de Krissi abrir um tubo que não estava funcionando no meu caso. A solução mostrada funcionou.
Você pode gravar no arquivo ... / fd / 0 do processo para enviar instruções para ele. A única desvantagem é que você também precisa encerrar o processo do bash, que executa o loop infinito depois que o servidor foi desligado.
fonte