Search code examples
shelldockerstdinfile-descriptorio-redirection

Keeping access to STDIN of a program run in the background via a FIFO


So I have a docker image, containing a minecraft server. A minecraft server takes input from the STDIN, so after starting the server with java -jar server.jar I can feed it commands (to stop the server for example) by typing it in the console.

Ideally I want to start the server in a shellscript that looks something this:

#!/bin/sh

.. some initialization ..

exec java -Xmx$RAM -Xms$RAM -jar server.jar

This way the java executable takes over the process, so that it can be gracefully terminated when docker sends a SIGTERM.

The issue comes when I want to keep an artificial STDIN, that allows me to executes commands onto the server via another script. To do this I made a FIFO that represents the console like so:

rm -f console; mkfifo console

I'm not sure how I can redirect this FIFO into the process this way though. I'm reading the fifo using cat in a while-loop like so

while true; do cat console; done

And thought about doing something like this:

while true; do cat console; done | exec java -jar server.jar

Or something like this:

exec java -jar server.jar < <(while true; do cat console; done)

For the latter, I've looked at bash: pipe data into an exec'd command which unfortunately gives me syntax error: unexpected redirection

I've also tried this:

while true; do cat console; done >&0 &

exec java -jar server.jar

which seems to freeze the server while it's starting.

I have no idea why all of this is not working, and I don't know how I can make it work.

To be clear of what I want to achieve:

  • Have java (the server) take over the main process
  • Have a FIFO redirected to the STDIN of the server

It sounds so simple to me, but I just cannot make it happen. Any help would be greatly appreciated.


Solution

  • I just found out that the < <(command) syntax is not supported in /bin/sh but it is support in /bin/bash.

    After switching to that, my final line is:

    exec java -jar server.jar < <(tail -f console)
    

    Sometimes you just have to accept that you have to install more dependencies..