3

I had a Ubuntu based Amazon EC2 server where I was running my java based application. For this I had written a init script which was running perfectly and as follows

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

:

Now I have moved my server from Ubuntu to Amazon Linux AMI. So I have changed above init script as follows

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

I have a trouble in replacing the following main lines in start and stop functions

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

and

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

Amazon Linux replaces 'start-stop-daemon' with 'daemon' and with the help of man page I have changed above lines as follows

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

and

killproc --pidfile

But it is giving following error.

Starting myserver: ./myserver: Usage: daemon [+/-nicelevel] {program}

Will anybody guide me to write the proper init script for Amazon Linux AMI?

EDIT:

In start function I did the following changes and now this script starts the daemon but fails to create a pidfile and hence it fails to stop the daemon

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

So can anyone suggest me about what is wrong in it and what i need to do so it should create pid file auomatically?

migrated from stackoverflow.com Mar 26 '15 at 15:51

This question came from our site for professional and enthusiast programmers.

  • SO questions are meant to last, so you should paste your code here rather than using Pastebin. – 4ae1e1 Mar 21 '15 at 13:31
  • @4ae1e1: It was very lengthy shell script so not pasted here. On SO only in one of question I saw somewhere that don't paste lengthy programs here. Use pastebin like service. – ganesh Mar 21 '15 at 13:35
  • I'm not sure you were reading the best suggestion. SO questions and answers should be self-contained. You are not encouraged to paste all your irrelevant code here — we're not here to help you debug full programs. Rather, you should create a minimal, complete, and verifiable example. Failing that, you can at least paste complete scripts as a backup. When a piece of code is long, the box becomes a fixed-height scrollable box, as in this screenshot: i.imgur.com/tGkrZ5T.png . Not that bad. – 4ae1e1 Mar 21 '15 at 13:42
  • Also, code should be in preformatted blocks, not blockquotes. – 4ae1e1 Mar 21 '15 at 13:43
3

I updated my script to following code. Although it is not able to create pidfile but it is working as I want. If anybody has better script then kindly post your answer.

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

EDIT:

Another Version of above script where I am creating pid file and using it to get status and stop the application. I think the following script is more reliable than above.

#!/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
  • are you saying that your latest version with echo $PID > $PIDFILE doesn't work? Are you sure there is a value for $PID. Add an echo PID=$PID to debug.. Otherwise, look at the permissions to your /var/run dir where you are writing the $PIDFILE. the process that is running the script must have write privileges in bot /var and /var/run. Good luck. – shellter Apr 3 '15 at 2:50
  • @shelter: No in first script it was not creating the pid file where I have mentioned daemon --pidfile PIDFILE. But in second I am creating it using echo $PID > $PIDFILE and it is working perfectly. – ganesh Apr 3 '15 at 5:46
  • In first script there was a problem that if my program crashes then lockfile was not getting deleted and it was failing in starting the application but the second version is more reliable. – ganesh Apr 3 '15 at 5:47
0

Rather than rewriting the script I opted to installing an rpm of the 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

Source can be found here: https://github.com/willgarcia/start-stop-daemon

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.