Пытаясь понять, как использовать FIFO с этим сценарием запуска init.d - PullRequest
0 голосов
/ 05 мая 2011

Резюме: Нужна помощь с использованием именованного канала в моем скрипте запуска init.d. Труба не работает, когда она начинается, и я не могу понять, как ее убить.

У меня есть этот скрипт запуска, который я использую в Ubuntu 10.04 x64 для запуска сервера minecraft. Единственное, что мне нужно, это настроить чтение FIFO, чтобы я мог передавать команды на сервер из оболочки. Я сделал файл .fifo, и он прекрасно работает, если я запускаю сервер вручную из оболочки следующим образом:

tail -f minecraft.fifo | /usr/lib/jvm/java-6-sun/bin/java -Xmx2048M -Xms2048M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=2 -XX:+AggressiveOpts -jar minecraft_server.jar &

Я испытываю трудности, когда подключаю этот tail -f minecraft.fifo к сценарию инициализации. Когда я запускаю сервис, запускается tail -f minecraft.fifo; но он не передает команды на сервер minecraft, как это происходит, когда я запускаю его вручную из оболочки.

Кроме того, я не понимаю, как остановить именованную трубу. До сих пор я решил, что мне нужно сохранить PID процесса, а затем убить этот PID во время остановки. Но я не понимаю, как получить PID из $! в переменную, чтобы я мог ее вспомнить.

Имеет смысл? Хвост не работает, когда я вызываю его, и я не понимаю, как убить процесс хвоста.

Вот действующий скрипт запуска, который не содержит именованный канал:

#!/bin/bash
# /etc/init.d/minecraft

### BEGIN INIT INFO
# Provides:   minecraft
# Required-Start: $local_fs $remote_fs
# Required-Stop:  $local_fs $remote_fs
# Should-Start:   $network
# Should-Stop:    $network
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description:    Minecraft server
# Description:    Starts the minecraft server
### END INIT INFO

#Settings
JARFILE='minecraft_server.jar'
USERNAME="minecraft"
MCHOME='/home/minecraft'
NAMEDPIPE='minecraft.fifo'
DAEMON="/usr/lib/jvm/java-6-sun/bin/java -Xmx2048M -Xms2048M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=2 -XX:+AggressiveOpts -jar $JARFILE nogui $"

ME=`whoami`
as_user() {
  if [ $ME == $USERNAME ] ; then
    bash -c "$1"
  else
    su - $USERNAME -c "$1"
  fi
}

mc_start() {
  if ps ax | grep -v grep | grep -v -i SCREEN | grep $JARFILE > /dev/null
  then
    echo "Tried to start but $JARFILE was already running!"
  else
    echo "$JARFILE was not running... starting."
    cd $MCHOME
    as_user "cd $MCHOME && screen -dmS minecraft $DAEMON"
    sleep 7
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $JARFILE > /dev/null
    then
      echo "$JARFILE is now running."
    else
      echo "Could not start $JARFILE."
    fi
  fi
}

mc_stop() {
        if ps ax | grep -v grep | grep -v -i SCREEN | grep $JARFILE > /dev/null
        then
                echo "$JARFILE is running... stopping."
                as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
                as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
                sleep 10
                as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
                sleep 7
        else
                echo "$JARFILE was not running."
        fi
        if ps ax | grep -v grep | grep -v -i SCREEN | grep $JARFILE > /dev/null
        then
                echo "$JARFILE could not be shut down... still running."
        else
                echo "$JARFILE is shut down."
        fi
}


#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  status)
    if ps ax | grep -v grep | grep -v -i SCREEN | grep $JARFILE > /dev/null
    then
      echo "$JARFILE is running."
    else
      echo "$JARFILE is not running."
    fi
    ;;

  *)
  echo "Usage: /etc/init.d/minecraft {start|stop|status|restart}"
  exit 1
  ;;
esac

exit 0

Если я изменю переменную DAEMON таким образом, скрипт ее запустит, и хвост -f можно найти с помощью ps -ef:

DAEMON="tail -f minecraft.fifo | /usr/lib/jvm/java-6-sun/bin/java -Xmx2048M -Xms2048M -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalPacing -XX:ParallelGCThreads=2 -XX:+AggressiveOpts -jar $JARFILE nogui $"

Но если я отправлю команду на minecraft.fifo, сервер ее не прочитает. Глядя на PS, кажется, что tail -f minecraft.fifo фактически запускается в отдельном процессе. Это может быть проблемой.

Примечание: я использую команду SCREEN для вызова DAEMON, потому что мне нужен был способ подключиться к работающему серверу и выдавать ему команды. Поэтому я просто показываю -r как пользователь minecraft, и тогда я могу работать с сервером. Как только этот fifo заработает, мне больше не понадобятся экранные материалы. Так что, если это мешает, его можно удалить.

Что касается его убийства; если я положу хвост killall в mc_stop, он будет работать. Но это убивает все хвосты, и у меня бегут другие, которых я не хочу убивать. До сих пор я не выяснил, как запустить сервер таким образом, чтобы хранить PID, чтобы я мог убить его с помощью PID. Или запустить хвост с уникальным именем процесса, чтобы я мог убить его, не подвергая опасности другие хвосты.

Любые мысли о том, как правильно запустить сервер, используя именованный канал; а то как правильно его остановить?

Ответы [ 3 ]

1 голос
/ 05 мая 2011
1 голос
/ 05 мая 2011

Вместо того, чтобы использовать tail -f, почему бы не запустить скрипт, отслеживающий именованный канал FIFO?

#!/bin/bash
NAMEDPIPE="/path/to/minecraft.fifo"

STOP_NOW="no"
STOP_SIGNAL="there is no place like home"
DELAY="1s"

while [[ $STOP_NOW == "no" ]]; do
  read INCOMING_THINGS
  if [[ $STOP_SIGNAL == "$INCOMING_THINGS" ]]; then
    STOP_NOW="yes"
  else
    printf "%s\n" "$INCOMING_THINGS"
    sleep $DELAY
  fi
done < $NAMEDPIPE

exit 0

Протестируйте его, используя scriptname.sh, и, если вам нравится, добавьте в него scriptname.sh | whatever_commands_here,Или даже nohup scriptname.sh | whatever_commands &.

Отправьте сигнал there is no place like home\n на именованный канал, и scriptname.sh должен завершиться изящно.

(надеюсь, я не неправильно понял вашу проблему.)

0 голосов
/ 07 мая 2011

Хорошо, я только что перевернул лицо и понял, что мне не нужно использовать fifo, поскольку я уже использую SCREEN для передачи ему команд через mc_stop.(Я не писал сценарий запуска, я просто пытаюсь настроить его, поэтому не очень хорошо с ним знаком)

screen -p 0 -S minecraft -X eval 'stuff \ "скажем SERVER SHUTTING DOWNВ 10 СЕКУНД. Сохранение карты ... \ "\ 015 '"

Это достигло именно того, для чего я хотел использовать fifo.

ТАК ... мой вопрос был глупым.проблема решена.

@ pepoluan; большое спасибо за помощь. Я очень ценю ответ. Я пытался использовать сценарий, и он работал, но он также сделал что-то очень странное. Он успешно отправил командуthe fifo. Но затем он вошел в странный цикл и отправил на сервер какую-то пустую команду. Сервер распознал первую команду, а затем начал выводить «команда не распознана». Какая команда не была распознана, является загадкой, так какотсутствует в журналах и не отображается в консоли Minecraft. Однако я продолжу работать с вашим сценарием, чтобы лучше понять, что такое fifo. Я попытался проголосовать за ваш ответЯ очень ценю, но stackexchange сказал мне, что у меня еще недостаточно высокая репутация.Так что, если кто-то еще может проголосовать за него;пожалуйста.

...