Send command to a background process

If you don't want to be limited to signals, your program must support one of the Inter Process Communication methods. See the corresponding Wikipedia article.

A simple method is to make it listen for commands on a Unix domain socket.


For how to send commands to a server via a named pipe (fifo) from the shell see here:

Redirecting input of application (java) but still allowing stdin in BASH

How do I use exec 3>myfifo in a script, and not have echo foo>&3 close the pipe?


Named Pipes are your friend. See the article Linux Journal: Using Named Pipes (FIFOs) with Bash.


Based on the answers:

  1. Writing to stdin of background process
  2. Accessing bash command line args $@ vs $*
  3. Why my named pipe input command line just hangs when it is called?
  4. Can I redirect output to a log file and background a process at the same time?

I wrote two shell scripts to communicate with my game server.


This first script is run when computer start up. It does start the server and configure it to read/receive my commands while it run in background:

start_czero_server.sh

#!/bin/sh

# Go to the game server application folder where the game application `hlds_run` is
cd /home/user/Half-Life

# Set up a pipe named `/tmp/srv-input`
rm /tmp/srv-input
mkfifo /tmp/srv-input

# 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.
cat > /tmp/srv-input &

# The PID of this command is saved in the /tmp/srv-input-cat-pid file
# for latter kill.
# 
# 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`.
echo $! > /tmp/srv-input-cat-pid

# Start the server reading from the pipe named `/tmp/srv-input`
# And also output all its console to the file `/home/user/Half-Life/my_logs.txt`
#
# Replace the `./hlds_run -console -game czero +port 27015` by your application command
./hlds_run -console -game czero +port 27015 > my_logs.txt 2>&1 < /tmp/srv-input &

# Successful execution 
exit 0

This second script it just a wrapper which allow me easily to send commands to the my server:

send.sh

half_life_folder="/home/jack/Steam/steamapps/common/Half-Life"

half_life_pid_tail_file_name=hlds_logs_tail_pid.txt
half_life_pid_tail="$(cat $half_life_folder/$half_life_pid_tail_file_name)"

if ps -p $half_life_pid_tail > /dev/null
then
    echo "$half_life_pid_tail is running"
else   
    echo "Starting the tailing..."
    tail -2f $half_life_folder/my_logs.txt &
    echo $! > $half_life_folder/$half_life_pid_tail_file_name
fi

echo "$@" > /tmp/srv-input
sleep 1

exit 0

Now every time I want to send a command to my server I just do on the terminal:

./send.sh mp_timelimit 30

This script allows me to keep tailing the process on your current terminal, because every time I send a command, it checks whether there is a tail process running in background. If not, it just start one and every time the process sends outputs, I can see it on the terminal I used to send the command, just like for the applications you run appending the & operator.


You could always keep another open terminal open just to listen to my server server console. To do it just use the tail command with the -f flag to follow my server console output:

./tail -f /home/user/Half-Life/my_logs.txt

Tags:

Bash

Process