概要: init.d 起動スクリプトで名前付きパイプを使用する方法を探しています。起動時にパイプが機能せず、それを殺す方法がわかりません。
Minecraft サーバーを起動するために Ubuntu 10.04 x64 で使用しているこの起動スクリプトがあります。シェルからサーバーにコマンドを渡すことができるように、読み取り 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 &
私が苦労しているのは、そのテール -f minecraft.fifo を init スクリプトにプラグインするときです。サービスを開始すると、「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 を呼び出しています。したがって、ユーザー minecraft として -r をスクリーニングするだけで、サーバーを操作できます。ただし、この fifo が機能するようになると、画面の要素は必要なくなります。それで邪魔になったら取り外せます。
殺すのもよし。mc_stop に killall テールを配置すると、機能します。しかし、それはすべての尾を殺し、私は殺したくない他のものを実行しています。これまでのところ、PID を使用して強制終了できるように、PID を格納する方法でサーバーを起動する方法を理解していません。または、テールを一意のプロセス名で開始して、他のテールを危険にさらすことなくすべてを強制終了できるようにします。
名前付きパイプを使用してサーバーを適切に起動する方法についての考え; そして、それを適切に停止する方法は?