2011-05-05 2 views
0

요약 : init.d 시작 스크립트에서 명명 된 파이프를 사용하여 도움말을 찾고 있습니다. 파이프가 시작될 때 파이프가 작동하지 않아 파이프를 죽이는 방법을 알 수 없습니다.이 init.d 시작 스크립트에서 FIFO를 사용하는 방법을 알아 내려고 애 쓰고 있습니다.

저는 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 & 

는 내가 연결하면 그 init 스크립트에 꼬리 -f minecraft.fifo . 서비스를 시작하면 "tail -f minecraft.fifo"가 시작됩니다. 하지만 쉘에서 수동으로 시작할 때처럼 명령을 내 크래프트 서버에 전달하지 않습니다.

또한 명명 된 파이프를 중지하는 방법을 알지 못합니다. 지금까지 나는 프로세스의 PID를 저장 한 다음 중지하는 동안 해당 PID를 종료해야한다고 생각했습니다. 하지만 PID를 $에서 꺼내는 방법을 알지 못합니다! 내가 그것을 기억할 수 있도록 변수에 추가하십시오.

의미가 있습니까? 꼬리는 내가 그것을 호출 할 때 작동하지 않으며 꼬리 과정을 죽이는 방법을 알아 내지 못합니다. 여기

는 명명 된 파이프 포함되지 않은 기능 시작 스크립트입니다 : 그래서, 스크립트를 시작 않는 한 나는 DAEMON 변수를 수정하는 경우

#!/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 

을, 꼬리는 -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가 실제로 별도의 프로세스에서 시작하는 것처럼 보입니다. 그것은 문제 일 수 있습니다.

참고 : DAEMON을 호출하려면 SCREEN 명령을 사용하고 있습니다. 실행중인 서버로 이동하여 명령을 실행해야하기 때문입니다. 그래서 나는 사용자 minecraft로서 screen -r을 실행 한 다음 서버로 작업 할 수 있습니다. 그러나이 FIFO가 작동하면 더 이상 화면이 필요하지 않습니다. 그렇게되면 방해받을 수 있습니다.

죽이는 방법; mc_stop에 killall tail을 넣으면 작동합니다. 그러나 그것은 모든 꼬리를 죽이고 나는 죽이기를 원하지 않는 달리기를합니다. 지금까지 PID를 저장하는 방식으로 서버를 시작하는 방법을 알아 내지 못 했으므로 PID를 사용하지 못하게 할 수 있습니다. 또는 고유 한 프로세스 이름으로 꼬리를 시작하여 다른 꼬리를 위험에 빠뜨리지 않고 죽일 수 있습니다.

명명 된 파이프를 사용하여 서버를 올바르게 시작하는 방법에 대한 생각; 어떻게 제대로 멈출 수 있을까요?

+0

사용자 응답을 '귀하의 문제에 대한 대답'으로 '수락'할 수 있으며 작성자에게 15 점을 부여합니다. 원하는 답변의 왼쪽 상단에있는 아래쪽 화살표 근처에있는 체크 표시 (예 : http://i.imgur.com/uqJeW.png)를 누르기 만하면됩니다. 행운을 빕니다! – shellter

답변

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 | whatever_commands_here로 원하는대로라면, 소수를 scriptname.sh를 사용합니다. 또는 심지어 nohup scriptname.sh | whatever_commands &.

there is no place like home\n을 명명 된 파이프로 보내고 scriptname.sh은 정상적으로 종료되어야합니다.

(나는 당신의 문제를 오해하지 않았 으면 좋겠다.)

여기에있는 쉘에서 명명 된 파이프 (FIFO)를 통해 서버에 명령을 보내는
+0

답변 해 주셔서 대단히 감사드립니다. 나는 지금 이걸 가지고 놀거야. 내 init.d 시작 스크립트 내에서 이것을 사용하려면; 시작 스크립트가 $ 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

+0

@Tahnka 글쎄, 스크립트는'tail -f minecraft.fifo'를 대신합니다. 데몬에 넣으려고. – pepoluan

0

난 그냥 facepalmed 내가 필요하지 않은 것을 깨달았다 확인 이미 mc_stop을 통해 명령을 전달하기 위해 스크린을 사용하고 있기 때문에 FIFO를 사용합니다. (나는 시작 스크립트를 작성하지 않았다. 단지 그것을 조정하려고 시도했기 때문에 그것에 익숙하지 않았다.)

화면 -p 0 -S minecraft -X eval 'stuff \ "는 10에서 서버 셧다운을 말한다. 나는 위해 FIFO를 사용하고 싶었 정확히 무엇을 달성 SECONDS. 저장지도 ... \ "\ 015 '"

.

SO ... 내 바보 같은 질문이었다.이 문제는 해결됩니다.

@pepoluan; 도와 주셔서 대단히 감사합니다. 답장을 정말 고맙게 생각합니다. 스크립트를 사용하려고 시도했지만 효과가 있었지만 매우 이상한 일도했습니다. mmand 그리고 fifo. 그러나 이상한 루프로 들어가 서버에 null 명령을 보냈습니다. 서버가 첫 번째 명령을 인식 한 후 "명령을 인식 할 수 없음"을 반향하기 시작했습니다. 어떤 명령이 로그에 없으며 minecraft 콘솔에 표시되지 않았기 때문에 신비가 인식되지 않았습니다. 그러나 나는 필자의 스크립트로 계속 작업 할 것이므로 fifo를 더 깊이 이해할 수있을 것입니다. 나는 당신의 응답을 감사 하셔서 투표하려고 시도했지만 stackexchange는 내가 아직 충분히 높은 평판을 갖지 못했다고 말했다. 그래서 다른 누군가가 나를 위해 그를 투표 할 수 있다면; 부디.

관련 문제