Отправить команду в фоновый процесс

У меня есть ранее запущенный процесс (process1.sh), который работает в фоновом режиме с PID 1111 (или другим произвольным числом). Как я мог отправить что-то вроде command option1 option2 к этому процессу с PID 1111?

Я не хочу начинать новый process1.sh!

6 ответов

Решение

Именованные трубы - ваш друг. Смотрите статью Linux Journal: Использование именованных каналов (FIFO) с Bash.

На основании ответов:

  1. Запись в stdin фонового процесса
  2. Доступ к аргументам командной строки bash $@ vs $*
  3. Почему моя входная командная строка именованного канала просто зависает, когда она вызывается?
  4. Можно ли перенаправить вывод в файл журнала и одновременно запустить процесс в фоновом режиме?

Я написал два сценария оболочки для связи с моим игровым сервером.


Этот первый скрипт запускается при запуске компьютера. Он запускает сервер и настраивает его на чтение / получение моих команд, пока он работает в фоновом режиме:

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

Этот второй скрипт это просто оболочка, которая позволяет мне легко отправлять команды на мой сервер:

send.sh

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

half_life_pid_tail_file_name=my_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

Теперь каждый раз, когда я хочу отправить команду на свой сервер, я просто делаю на терминале:

./send.sh mp_timelimit 30

Этот скрипт позволяет мне следить за процессом, который вы можете использовать на текущем терминале, потому что каждый раз, когда я отправляю команду, он проверяет, работает ли хвостовой процесс в фоновом режиме. Если нет, он просто запускается один раз и каждый раз, когда процесс отправляет выходные данные, я вижу его на терминале, который использовал для отправки команды, так же, как для приложений, которые вы запускаете, добавляя & оператор.


Вы всегда можете оставить другой открытый терминал открытым только для прослушивания консоли моего сервера. Для этого просто используйте tail команда с -f флаг, чтобы следовать за выводом моей консоли сервера:

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

Вы можете использовать Баш coproc comamnd. (доступно только в 4.0+) - это как в ksh |&

проверьте это для примеров http://wiki.bash-hackers.org/syntax/keywords/coproc

Если вы не хотите ограничиваться сигналами, ваша программа должна поддерживать один из методов межпроцессного взаимодействия. Смотрите соответствующую статью в Википедии.

Простой способ - заставить его прослушивать команды в сокете домена Unix.

Вы не можете отправлять новые аргументы запущенному процессу.

Но если вы реализуете этот процесс или его процесс, который может принимать аргументы из канала, тогда поможет другой ответ.

Другие вопросы по тегам