Escrevendo para stdin do processo em segundo plano

25

Estou em uma caixa do Ubuntu 10.04 e iniciei um servidor em segundo plano (myserver &) através do ssh. Ele está funcionando bem, mas preciso de uma maneira de acessar o stdin do servidor, pois a única maneira de controlar o servidor é através desse método.

Existe alguma maneira de chegar ao stdin de um processo já em execução para que eu possa escrever nele (e espero ler seu stdout)? Obviamente, se eu estivesse fazendo isso agora, começaria com um FIFO redirecionando para stdin, mas infelizmente é um pouco tarde para isso agora.

Alguma ideia?

Tajmorton
fonte
Você não poderia simplesmente trazê-lo de volta ao primeiro plano? ('jobs' listará seu processo atual em segundo plano, 'fg $ X' trará o job de volta ao primeiro plano, ctrl + b pausará o job e retornará você ao seu shell, enquanto 'bg' continuará o processo pausado no )
symcbean

Respostas:

10

Você pode tentar escrever no diretório / proc pid. Digamos que o pid dos seus daemons seja 2000, tente escrever em / proc / 2000 / fd / 0

katriel
fonte
Obrigado ... Achei isso logo depois que postei isso (depois de um dia de exibição - típico). Isso parece funcionar (na medida em que realmente envia dados para o programa). Infelizmente, o programa não aceita os comandos. Eu testei executando o servidor no meu computador local e, com certeza, vejo os dados aparecerem, mas o programa não reconhece os comandos. Eu tenho que pressionar manualmente enter no terminal do servidor e, em seguida, ele diz apenas comando não reconhecido. Talvez alguma estranheza de java? Estou preso ...
tajmorton
11
que tal echo -e "algo \ n"> / proc / 2000 / fd / 0?
Katriel # 8/10
Na verdade, isso não é sempre sworking como / proc / <pid> / fd / 0 pontos para / dev / pts <algum número> em pelo menos alguns sistemas ...
bk138
A primeira resposta para serverfault.com/questions/178457/… observa que essa abordagem realmente não funciona.
barrycarter
2
Isso realmente não funciona. Seu shell normalmente (quando há tubos ou redirecionamentos são usados) inicia um comando com descritores de arquivos 0através de 2conjunto para o mesmo arquivo, que normalmente é um terminal virtual (algo como /dev/pty/...). O comando então do FD 0e grava no FD 1e 2se comunica com o terminal virtual (por exemplo, através do SSH ou diretamente com o emulador do terminal). Se qualquer outro processo acessar esse arquivo (por exemplo, através /proc), acontece exatamente a mesma coisa, ou seja, gravar nele grava no terminal e não no comando.
Feuermurmel 19/09/16
29

Você pode iniciar o servidor com um pipe nomeado (fifo) como entrada:

mkfifo /tmp/srv-input
cat > /tmp/srv-input &
echo $! > /tmp/srv-input-cat-pid
cat /tmp/srv-input | myserver &

A cat > /tmp/srv-input &é importante para evitar o servidor para receber um EOF. Pelo menos um processo deve ter o fifo aberto por escrito para que seu servidor não receba um EOF. O PID deste comando é salvo no /tmp/srv-input-cat-pidarquivo para posterior morte.

No seu caso em que você já iniciou seu servidor, é necessário usar um depurador, como o gdbanexo ao seu processo para redirecioná-lo stdinpara o fifo:

gdb -p PID
call close(0)
call open(0, "/tmp/srv-input", 0600)

E, em seguida, faça algo como abaixo para enviar informações ao seu servidor (em outra janela do terminal, se necessário):

echo "command" > /tmp/srv-input

Para enviar um EOF ao seu servidor, você precisa interromper o cat > /tmp/srv-inputprocesso no qual o PID foi salvo /tmp/srv-input-cat-pid file.

No caso do GDB, basta sair do GDB e o EOF será enviado.

jfg956
fonte
11
essa é uma abordagem muito mais portátil do que a do @katriel, já que / proc / 2000 / fd / 0 não é padrão em todos os sistemas.
precisa saber é o seguinte
O truque com o "cat> / tmp / srv-input &" me salvou algumas dores de cabeça. Obrigado!
precisa saber é o seguinte
Que tal mkfifo /tmp/srv-input; tail -f /tmp/srv-input | myserver &? Isso vai manter o aberto da tubulação, bem ...
bk138
@ bk138: parece que a cauda deve funcionar, mas só há uma maneira de saber com certeza: teste.
jfg956
tailnão trabalho, mas anexado este para terminar o trabalho: cat /tmp/srv-input | myserver; kill -9 cat / tmp / srv-input-cat-pid` && rm / tmp / srv-input-gato * `
Thiago Macedo
4

O mesmo que acima, mas 'gato' não funcionou para mim. O arquivo obteve EOF e terminou após o envio de um comando.

Isso funcionou para mim:

#!/bin/bash

mkfifo /tmp/srv-input
tail -f /tmp/srv-input | myserver &
Tamir
fonte