I'm on an Ubuntu 10.04 box, and started a server in the background (myserver &) over ssh. It's been running fine, but I need a way to get at the server's stdin, as the only way to control the server is through this method.
Is there some way to get at the stdin of an already-running process so I can write to it (and hopefully read its stdout)? Obviously, if I were going to be doing this now, I'd start it with a FIFO redirecting to stdin, but unfortunately it's a little late for that now.
Any ideas?
You could start you server with a named pipe (fifo) as its input:
The
cat > /tmp/srv-input &
is important to avoid your server to receive a EOF. At least one process must have the fifo opened in writing so your server does not receive a EOF. The PID of this command is saved in the/tmp/srv-input-cat-pid
file for latter kill.In your case where you've already started your server, you have to use a debugger such as
gdb
to attach to your process to redirect itsstdin
to the fifo:And then do something like bellow to send input to your server (in another terminal window if necessary):
To send a EOF to your server, you need to kill the
cat > /tmp/srv-input
process which PID has been saved in the/tmp/srv-input-cat-pid file
.In the case of GDB, just quit GDB and EOF will be sent.
You could try writing to it's /proc pid directory. Say your daemons' pid is 2000, try writing to /proc/2000/fd/0
Same as above, but 'cat' did not work for me. The file got EOF and ended after sending one command.
This worked for me:
There is a more elegant solution that solves the issues with
tail -f
andcat
Create a named pipe to route STDIN through:
mkfifo /data/in
.Block it for writing, so it does not get closed when your process read all of the current contents:
sleep infinity > /data/in &
.Sleeping forever is better than
tailf -f /dev/null
because tailf uses inotify resources and will be triggered each time some app sends data to /dev/null. You can see this by runningstrace
on it. It is also better thancat > /dev/null &
becausecat
will be itself disconnected from STDIN, which in turn will close/data/in
./data/in
providing STDIN:application < /data/in &
.This works better than using piping from tail
tail -f /data/in | application &
because the pipe will only get terminated if the tail stops, but if your application crashes the pipe will keep running.wait $(pidof application)
.This uses no resources and if the application crashes your script after the
wait
will be executed. You can add an application restart loop around it if you wish.trap 'kill -SIGTERM $(pidof app)' SIGTERM