Резюме: Нужна помощь с использованием именованного канала в моем скрипте запуска 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. Или запустить хвост с уникальным именем процесса, чтобы я мог убить его, не подвергая опасности другие хвосты.
Любые мысли о том, как правильно запустить сервер, используя именованный канал; а то как правильно его остановить?