Linux

如何將 Ubuntu 初始化腳本轉換為 Amazon Linux AMI 初始化腳本?

  • September 16, 2017

我有一個基於 Ubuntu 的 Amazon EC2 伺服器,我在其中執行基於 Java 的應用程序。為此,我編寫了一個執行完美的初始化腳本,如下所示

#! /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。所以我將上面的初始化腳本更改如下

#!/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: Usage: daemon

$$ +/-nicelevel $${程序}

有人會指導我為 Amazon Linux AMI 編寫正確的初始化腳本嗎?

編輯:

在啟動函式中,我做了以下更改,現在這個腳本啟動了守護程序,但未能創建 pidfile,因此無法停止守護程序

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

那麼任何人都可以向我建議它有什麼問題以及我需要做什麼以便它應該自動創建 pid 文件?

我將腳本更新為以下程式碼。雖然它無法創建 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

引用自:https://unix.stackexchange.com/questions/192691