Ubuntu 초기화 스크립트를 Amazon Linux AMI 초기화 스크립트로 변환하는 방법은 무엇입니까?

Ubuntu 초기화 스크립트를 Amazon Linux AMI 초기화 스크립트로 변환하는 방법은 무엇입니까?

Java 기반 애플리케이션을 실행하는 Ubuntu 기반 Amazon EC2 서버가 있습니다. 이를 위해 아래와 같이 완벽하게 작동하는 init 스크립트를 작성했습니다.

 #! /bin/sh
# set the environment variables that are used
PATH=/sbin:/usr/sbin:/bin:/usr/bin
JAVA_HOME=/usr/lib/jvm/java-6-sun/jre
JAVA=$JAVA_HOME/bin/java
DESC="My Application"
NAME="myserver"
DAEMON=$JAVA
DAEMON_HOME="/home/ganesh/MyServer/"
JAR=$DAEMON_HOME/MyServer.jar
DAEMON_ARGS="-Xms512m -Xmx4112m -jar $JAR"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/myserver
#the user that will run the script
USER=ganesh

# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh

# Define LSB log_* functions.
# Depend on lsb-base (>= 3.0-6) to ensure that this file is present.
. /lib/lsb/init-functions

#
# Function that starts the daemon/service
#
do_start()
{
        start-stop-daemon -N -10 -b --start -d $DAEMON_HOME --quiet --chuid $USER -m -p $PIDFILE --exec $DAEMON -- $DAEMON_ARGS \
                || return 2


        #Test to see if the engine has started
        start-stop-daemon -b --test --start -d $DAEMON_HOME --quiet --chuid $USER -m -p $PIDFILE --exec $DAEMON -- $DAEMON_ARGS >/dev/null 2>&1

    case "$?" in
        0) echo "[ FAIL ] App Engine has not started";;
        1) echo "[ OK ] App Engine has started";;
    esac                               
}

#
# Function that stops the daemon/service
#
do_stop()
{
        start-stop-daemon --stop --retry 120 --oknodo --pidfile $PIDFILE
        RETVAL="$?"
        rm -f $PIDFILE
        return "$RETVAL"
}

case "$1" in
  start)
        [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
        echo "Starting $DESC" "$NAME"

        do_start
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1
                                echo "[ FAIL ]";;              
        esac
        ;;

  stop)
        [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
        echo "Stopping $DESC" "$NAME"
        do_stop
        case "$?" in
                0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
        esac
        echo "[ OK ]"
        ;;
  restart)
        #
        # If the "reload" option is implemented then remove the
        # 'force-reload' alias
        #
        log_daemon_msg "Restarting $DESC" "$NAME"
        echo "Restarting $DESC" "$NAME"
        do_stop
        case "$?" in
          0|1)
                do_start
                case "$?" in
                        0) log_end_msg 0 ;;
                        1) log_end_msg 1 ;; # Old process is still running
                        *) log_end_msg 1 ;; # Failed to start
                esac
                ;;
          *)
                # Failed to stop
                log_end_msg 1
                ;;
        esac
        ;;
  *)
        echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
        exit 3
        ;;
esac

:

이제 서버를 Ubuntu에서 Amazon Linux AMI로 마이그레이션했습니다. 그래서 위의 init 스크립트를 다음과 같이 변경했습니다.

#!/bin/bash

# Source function library.
. /etc/init.d/functions

RETVAL=0
prog="myserver"
LOCKFILE=/var/lock/subsys/$prog
PIDFILE=/var/run/$prog.pid
PATH=/sbin:/usr/sbin:/bin:/usr/bin
JAVA=/usr/bin/java
DESC="MY Application"
DAEMON=$JAVA
DAEMON_HOME="/home/ganesh/MyServer"
JAR=$DAEMON_HOME/MyServer.jar
DAEMON_ARGS="-Xms512m -Xmx4112m -jar $JAR"
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/myserver
#the user that will run the script
USER=root

echo "All value sets"

start() {
        echo "IN start"
        echo -n "Starting $prog: "
        daemon --user $USER --chdir $DAEMON_HOME --pidfile $PIDFILE $DAEMON -- $DAEMON_ARGS
        RETVAL=$?
        [ $RETVAL -eq 0 ] && touch $LOCKFILE
        echo
        return $RETVAL
}

stop() {
        echo -n "Shutting down $prog: "
        killproc --pidfile
        RETVAL=$?
        [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
        echo
        return $RETVAL
}

status() {
        echo -n "Checking $prog status: "
        RETVAL=$?
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage1: $prog {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

시작 및 중지 기능에서 다음 주요 줄을 바꾸는 데 문제가 있습니다.

start-stop-daemon -N -10 -b --start -d $DAEMON_HOME --quiet --chuid
$USER -m -p $PIDFILE --exec $DAEMON -- $DAEMON_ARGS \
              || return 2

그리고

start-stop-daemon --stop --retry 120 --oknodo --pidfile $PIDFILE

Amazon Linux는 "start-stop-daemon"을 "daemon"으로 대체하고 매뉴얼 페이지의 도움을 받아 위 줄을 다음과 같이 변경했습니다.

daemon --user $USER --chdir $DAEMON_HOME --pidfile $PIDFILE $DAEMON -- $DAEMON_ARGS

그리고

killproc --pidfile

하지만 다음과 같은 오류가 발생합니다.

myserver 시작: ./myserver: 사용법: 데몬 프로세스 [+/-nicelevel] {program}

Amazon Linux AMI에 대한 올바른 초기화 스크립트를 작성하도록 안내해 줄 수 있는 사람이 있습니까?

편집하다:

시작 기능에서 다음과 같이 변경했으며 이제 이 스크립트는 데몬을 시작하지만 pidfile을 생성할 수 없으므로 데몬을 중지할 수 없습니다.

cd $DAEMON_HOME
daemon --user $USER --pidfile $PIDFILE $DAEMON $DAEMON_ARGS >/dev/null 2>&1 & 

그럼 누구든지 나에게 무엇이 문제인지, pid 파일을 자동으로 생성하려면 어떻게 해야 하는지 제안할 수 있습니까?

답변1

스크립트를 다음 코드로 업데이트했습니다. pidfile 생성에는 실패했지만 원하는 방식으로 작동합니다. 더 나은 스크립트가 있는 사람이 있으면 답변을 게시해 주세요.

#!/bin/bash

# chkconfig: 2345 95 05
# description: MY Application

# Source function library.
. /etc/init.d/functions

RETVAL=0
prog="myserver"
PIDFILE=/var/run/$prog.pid
LOCKFILE=/var/lock/subsys/$prog
PATH=/sbin:/usr/sbin:/bin:/usr/bin
JAVA=/usr/bin/java
DESC="MY Application"
DAEMON=$JAVA
DAEMON_HOME="/home/ganesh/MyServer/"
JAR=$DAEMON_HOME/MyServer.jar
DAEMON_ARGS="-Xms512m -Xmx4112m -jar $JAR"
SCRIPTNAME=/etc/init.d/myserver
#the user that will run the script
USER=root

#echo "All value sets"

start() {
    if [ -f $LOCKFILE ];
    then
        echo "$DESC is already running. Exiting."
        exit 1
    else
        echo -n "Starting $prog:"
        cd $DAEMON_HOME
        daemon --user $USER  --pidfile $PIDFILE $DAEMON $DAEMON_ARGS >/dev/null 2>&1 &
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && touch $LOCKFILE
    fi

    return $RETVAL
}

stop() {
        echo -n "Shutting down "$prog:
        kill -9  `ps -ef | grep "$JAR" | grep -v grep | awk '{ print $2 }'`        
        RETVAL=$?
        echo
        [ $RETVAL -eq 0 ] && rm -f $LOCKFILE
        return $RETVAL
}

check_status() {
        #echo -n "Checking $prog status: "
        status $prog
        RETVAL=$?
        return $RETVAL
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        check_status
        ;;
    restart)
        stop
        start
        ;;
    *)

        echo "Usage: $prog {start|stop|status|restart}"
        exit 1
        ;;
esac
exit $RETVAL

편집하다:

위 스크립트의 또 다른 버전인 pid 파일을 생성하고 이를 사용하여 상태를 가져오고 애플리케이션을 중지합니다. 내 생각에는 아래 스크립트가 위 스크립트보다 더 안정적이라고 생각합니다.

#!/bin/bash

# chkconfig: 2345 95 05
# description: MY Application

# Source function library.
. /etc/init.d/functions

RETVAL=0
prog="myserver"
PIDFILE=/var/run/$prog.pid
LOCKFILE=/var/lock/subsys/$prog
PATH=/sbin:/usr/sbin:/bin:/usr/bin
JAVA=/usr/bin/java
DESC="MY Application"
DAEMON=$JAVA
DAEMON_HOME="/home/ganesh/MyServer/"
JAR=$DAEMON_HOME/MyServer.jar
DAEMON_ARGS="-Xms512m -Xmx4112m -jar $JAR"
SCRIPTNAME=/etc/init.d/myserver
#the user that will run the script
USER=root

#echo "All value sets"

start() {
    if [ -f $PIDFILE ]; then
        PID=`cat $PIDFILE`
        if [ -z "`pgrep $PID`" ] && [ "$PID" != "`ps aux|grep -vE 'grep|runuser|bash'|grep -w "$JAR"|awk '{print $2}'`" ]; then
            printf "%s\n" "Process dead but pidfile exists"
        else
            printf "$prog is already running!\n"
        fi
    else
        printf "%-50s" "Starting $prog ..."
        cd $DAEMON_HOME
        daemon --user $USER $DAEMON $DAEMON_ARGS >/dev/null 2>&1 &
        sleep 5
        PID=`ps aux|grep -vE 'grep|runuser|bash'|grep -w "$JAR"|awk '{print $2}'`
        if [ -z "$PID" ]; then
            printf "[ \e[31mFAIL\033[0m ]\n"
        else
            echo $PID > $PIDFILE
            printf "[ \e[32mOK\033[0m ]\n"
        fi
    fi
}

stop() {
    printf "%-50s" "Shutting down $prog:"
    if [ -f $PIDFILE ]; then
        PID=`cat $PIDFILE`
        kill -HUP $PID 2>/dev/null
        printf "[ \e[32mOK\033[0m ]\n"
        rm -f $PIDFILE
    else
        printf "[ \e[31mFAIL\033[0m ]\n" 
    fi
}

check_status() {
    printf "%-50s" "Checking $prog ..."
    if [ -f $PIDFILE ]; then
        PID=`cat $PIDFILE`
        if [ -z "`pgrep $PID`" ] && [ "$PID" != "`ps aux|grep -vE 'grep|runuser|bash'|grep -w "$JAR"|awk '{print $2}'`" ]; then
            printf "%s\n" "Process dead but pidfile exists"
        else
            printf "[ \e[32mRUNNING\033[0m ]\n"
        fi
    else
        printf "[ \e[31mSTOPPED\033[0m ]\n"
    fi
}

case "$1" in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        check_status
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $prog {start|stop|status|restart}"
        exit 1
        ;;
esac
exit 1

답변2

스크립트를 다시 작성하는 대신 start-stop-daemon.

# Follow instructions here to make the RPM available to yum
# https://packagecloud.io/willgarcia/start-stop-daemon/install
# and then you can run:
yum install start-stop-daemon

소스는 여기에서 찾을 수 있습니다:https://github.com/willgarcia/start-stop-daemon

관련 정보