2011-05-05 67 views
0

摘要:在我的init.d启动脚本中寻找一些使用命名管道的帮助。管道启动时不起作用,我无法弄清楚如何杀死它。努力弄清楚如何在init.d启动脚本中使用FIFO

我有这个启动脚本,我在Ubuntu 10.04 x64中用来启动一个minecraft服务器。我需要的一件事是设置一个读取FIFO,以便我可以将命令从shell传递到服务器。我做了一个.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 。当我开始服务时,“tail -f minecraft.fifo”启动;但它不会像命令从shell手动启动命令那样将命令传递到Minecraft服务器。

此外,我不知道如何停止命名管道。到目前为止,我想我需要保存该进程的PID,然后在停止期间杀死该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,似乎尾巴-f minecraft.fifo实际上是从一个单独的过程开始的。这可能是问题所在。

注意:我使用SCREEN命令来调用DAEMON,因为我需要一种方法来跳转到正在运行的服务器并向其发出命令。所以我只是屏幕-r作为用户的Minecraft,然后我可以使用服务器。但是,一旦这个fifo工作,我将不再需要屏幕的东西。所以,如果这样做,它可以被删除。

至于杀死它;如果我在mc_stop中放置killall尾部,它就会起作用。但是那杀死了所有的尾巴,并且我有其他人在跑,我不想杀人。到目前为止,我还没有想出如何以存储PID的方式启动服务器,这样我就可以使用PID来杀死它。或者以一个独特的流程名称开始尾巴,这样我就可以在不危害其他尾巴的情况下打败尾巴。

有关如何使用命名管道正确启动服务器的任何想法;然后如何正确地阻止它?

+0

你可以'接受'一个用户的答复作为'你的问题的答案',这将给作家15分。您只需要在您喜欢的答案左上角的上下箭头旁边勾选复选标记,即http://i.imgur.com/uqJeW.png。祝你好运! – shellter 2011-05-05 16:09:22

回答

1

而不是使用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

非常感谢您的回复。我现在就玩这个。为了在我的init.d启动脚本中使用它,你是否建议启动脚本实际启动这个使用启动命令的外部shell脚本作为$ INCOMING_THINGS?因此,启动脚本中的DAEMON变量将如下所示: DAEMON =“/ home/minecraft/fifo_startup.sh |/usr/lib/jvm/java-6-sun/bin/java -Xmx2048M -Xms2048M -XX :+ UseConcMarkSweepGC -XX:+ CMSIncrementalPacing -XX:ParallelGCThreads = 2 -XX:+ AggressiveOpts -jar minecraft.jar nogui $“ – Tahnka 2011-05-05 06:35:07

+0

@Tahnka那么脚本会替换'tail -f minecraft.fifo',所以是的,我想这就是把它放进DAEMON – pepoluan 2011-05-05 06:49:29

0

好吧我只是facepalmed并意识到,我并不需要使用fifo,因为我已经使用SCREEN通过mc_stop传递命令。 (我没有写启动脚本,我只是想调整它,所以不太熟悉它)

screen -p 0 -S minecraft -X eval'stuff \“说服务器关闭在10秒地图保存... \“\ 015' ”

这实现正是我想要使用FIFO来。

所以......我的是一个愚蠢的问题。这个问题解决。

@pepoluan;非常感谢您的帮助,我非常感谢他们的回应,我确实尝试过使用这个脚本,但是它也做了一些很奇怪的事情,前往fifo。但随后进入了一个奇怪的循环,并向服务器发送了一些空指令。服务器识别出第一个命令,然后开始回显“command not recognized”。没有识别出什么命令是一个谜,因为它不在日志中,也没有显示在Minecraft控制台中。不过,我会继续与您​​的脚本一起工作,以便我可以进一步了解fifo。我试图在赞赏中投票赞成你的回应,但是stackexchange告诉我,我还没有足够高的声望。所以如果别人可以为我投票给他;请。