摘要:在我的 init.d 启动脚本中使用命名管道寻找一些帮助。管道启动时不工作,我不知道如何杀死它。
我有这个启动脚本,我在 Ubuntu 10.04 x64 中使用它来启动我的世界服务器。我需要做的一件事是设置一个读取 FIFO,以便我可以将命令从 shell 传递到服务器。我制作了一个 .fifo 文件,如果我从 shell 手动启动服务器,效果很好,如下所示:
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”启动;但它不会像我从 shell 手动启动它时那样将命令传递给 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 变量,脚本会启动它,并且可以使用 ps -ef 找到 tail -f:
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,因为我需要一种方法来跳转到正在运行的服务器并向其发出命令。所以我只是 screen -r 作为用户 minecraft 然后我可以使用服务器。然而,一旦这个 fifo 工作,我将不再需要屏幕的东西。因此,如果这妨碍了它,则可以将其删除。
至于杀了它;如果我在 mc_stop 中放一个 killall tail,它就可以工作。但这会杀死所有尾巴,而且我还有其他人在奔跑,我不想杀死。到目前为止,我还没有弄清楚如何以存储 PID 的方式启动服务器,以便我可以使用 PID 进行终止。或者以唯一的进程名称开始尾部,这样我就可以在不危及其他尾部的情况下杀死它。
关于如何使用命名管道正确启动服务器的任何想法;然后如何正确阻止它?