init.d启动脚本

init.d启动脚本

我尝试为glassfish软件创建一个init.d服务脚本。但似乎我对LSB init.d指南的理解不是最好的。

这是脚本应该执行的命令:

/opt/glassfish/bin/asadmin start-domain
/opt/glassfish/bin/asadmin stop-domain
/opt/glassfish/bin/asadmin restart-domain

我的脚本看起来像这样,但它不起作用。这是我第一次尝试制作 init.d 脚本。如果我做错了,请告诉我。

注意:请查看下面我更新的脚本编辑:

#!/bin/sh
#
### BEGIN INIT INFO
#
# Provides:     glassfish
# Required-Start:   $local_fs $remote_fs $network
# Required-Stop:    $local_fs $remote_fs $network
# Default-Start:    2 3 4 5
# Default-Stop:     0 1 6
# Short-Description:    Glassfish scipt (Non official)
# Description:  Start Glassfish domain as service.
#       Non official startup script.
#
### END INIT INFO

BASE=/opt/glassfish/bin
DEAMON=${BASE}/asadmin
USERID=root
NAME=glassfish
DESC="Glassfish domain service"
# PID file for the deamon
PIDFILE=/var/run/glassfish.pid
SCRIPTNAME=/etc/init.d/$NAME

# Exit if the package is not installed
[ -x "$DEAMON" ] || exit 0

# Using LSB functions to perform the operations
. /lib/lsb/init-functions

do_start()
{
    start-stop-deamon --start --quiet --pidfile $PIDFILE --exec $DEAMON start-domain -- $NAME_OPTIONS
}

do_stop()
{
    start-stop-deamon --stop --quiet --retry=TERM/30/KILL/5 --pidfile $PIDFILE --exec $DEAMON stop-domain
}

case $1 in
    start)
        if init_is_upstart; then
            exit 1
        fi
        log_deamon_msg "Starting $DESC"
        do_start
        case "$?" in
            0) sendsigs_omit 
               log_end_msg 0 ;;
            1) log_progress_msg "already started"
               log_end_msg 0 ;;
            *) log_end_msg 1 ;;
        esac

        ;;
    stop)
        if init_is_upstart; then
            exit 0
        fi
        log_deamon_msg "Stopping $DESC"
        do_stop
        case "$?" in
            0) log_end_msg 0 ;;
            1) log_progress_msg "already stopped"
               log_end_msg 0 ;;
            *) log_emd_msg 1 ;;
        esac

        ;;
    restart|force-reload)
        if init_is_upstart; then
            exit 1
        fi
        $0 stop
        $0 start
        ;;
    status)
        status_of_proc -p $PIDFILE $DEAMON && exit 0 || exit $?
        ;;
    *)
        echo "Usage: $SCRIPTNAME {start|stop|restart|status}" >&2
        exit 3
        ;;
esac

:       

当我执行“/bin/bash -x ./glassfish status”时,输出如下:

+ case "$FANCYTTY" in
+ true
++ /usr/bin/tput setaf 1
+ RED=''
++ /usr/bin/tput op
+ NORMAL=''
+ echo ' *  is not running'
 *  is not running
+ return 3
+ exit 3

但无论我启动还是停止都没关系。结果总是一样的。脚本不会启动glassfish域服务器。没有脚本一切都正常。

编辑:

我把脚本改成这样:

#!/bin/sh

### BEGIN INIT INFO
#
# Provides:     glassfish
# Required-Start:   $local_fs $remote_fs $network
# Required-Stop:    $local_fs $remote_fs $network
# Default-Start:    2 3 4 5
# Default-Stop:     0 1 6
# Short-Description:    Glassfish scipt (Non official)
# Description:  Start Glassfish domain as service.
#       Non official startup script
#
### END INIT INFO

# Using the LSB functions to perform the operations
. /lib/lsb/init-functions

BASE=/opt/glassfish/bin
NAME=glassfish
DAEMON=${BASE}/asadmin
SCRIPTNAME=/etc/init.d/$NAME

#PID file for the daemon
PIDFILE=/var/run/glassfish.pid

#If the daemon is not there, then exit
[ -x "$DAEMON" ] || exit 5

do_start()
{
    start-stop-daemon --start --quiet --pidfile $PIDFILE --exec $DAEMON start-domain
}

do_stop()
{
    start-stop-daemon --stop --quiet --pidfile $PIDFILE
}

case $1 in
    start)
        #Check PID file
        if [ -e $PIDFILE ]; then
            status_of_proc -p $PIDFILE $DAEMON "$NAME process" && status="0" || status="$?"
            # IF SUCCESS dont start again
            if [ $status = "0" ]; then
                exit
            fi
        fi

        #Start the daemon
        log_daemon_msg "Starting the process" "$NAME"
        if do_start; then
            log_end_msg 0
        else
            log_end_msg 1
        fi
        ;;

    stop)
        # Stop the daemon
        if [ -e $PIDFILE ]; then
            status_of_proc -p $PIDFILE $DAEMON "Stopping the $NAME process" && status="0" || status="$?"
            if [ "$status" = 0]; then
                do_stop
            fi
        else
            log_daemon_msg "$NAME process is not running"
            log_end_msg 0
        fi
        ;;

    restart)
        # Restart the daemon
            $0 stop && sleep 2 && $0 start
        ;;

    status)
        # Check status
        if [ -e $PIDFILE ]; then
            status_of_proc -p $PIDFILE $DAEMON "$NAME process" && exit 0 || exit $?
        else
            log_daemon_msg "$NAME Process is not running"
            log_end_msg 0
        fi
        ;;

    *)
        # Show help
        echo "Usage: $SCRIPTNAME {start|stop|restart}" >&2
        exit 3
        ;;
esac

更改后输出如下:

 * Starting the process glassfish                                                                                                                                                                                                            Waiting for domain1 to start .........
Successfully started the domain : domain1
domain  Location: /opt/glassfish/domains/domain1
Log File: /opt/glassfish/domains/domain1/logs/server.log
Admin Port: 4848
Command start-domain executed successfully.

现在它可以启动该进程了。然后在停止服务时出现下一个问题:

 * glassfish process is not running

但进程正在运行,脚本甚至没有尝试,只是中止。/var/run 下也没有 glassfish PID 文件。

答案1

我终于让它工作了!

如果有人对答案感兴趣。问题是 Glassfish 本身没有创建 PID 文件。因此,需要一个解决方法,即在后台启动程序(使用 &)并输出其 PID。

为了理解,我看了这些帖子:

帕特里克的回答

https://unix.stackexchange.com/questions/137519/start-stop-daemon-not-working-as-expected-no-pid-file-was-written

l0b0 的回答

https://stackoverflow.com/questions/9890062/how-to-run-a-program-and-know-its-pid-in-linux

kojiro 的回答

https://stackoverflow.com/questions/5163144/what-are-the-special-dollar-sign-shell-variables

Stack*(askUbuntu) 社区确实是一个很棒的社区!:)

完整的工作脚本如下:

#!/bin/sh

### BEGIN INIT INFO
#
# Provides:     glassfish
# Required-Start:   $local_fs $remote_fs $network
# Required-Stop:    $local_fs $remote_fs $network
# Default-Start:    2 3 4 5
# Default-Stop:     0 1 6
# Short-Description:    Glassfish scipt (Non official)
# Description:  Start Glassfish domain as service.
#       Non official startup script by Bernhard Sumser.
#
### END INIT INFO

# Using the LSB functions to perform the operations
# NOT needed because no LSB functions used
#. /lib/lsb/init-functions

BASE=/opt/glassfish/bin
NAME=glassfish
DAEMON=${BASE}/asadmin
SCRIPTNAME=/etc/init.d/$NAME

#PID file for the daemon
PIDFILE=/var/run/glassfish.pid

#If the DAEMON is not there, then exit
[ -x "$DAEMON" ] || exit 0


do_start()
{
    $DAEMON start-domain &
    # Wait for child to exit before continuing
    wait
    # Make file with last background PID
    echo $! > $PIDFILE

    # Didn't work because the programm prints from the background. Without moving to the bg no $! can be outputed to file
    #(($DAEMON start-domain) & echo $! > $PIDFILE &)
}

do_stop()
{
    $DAEMON stop-domain
    if [ -e $PIDFILE ]; then
        rm -f $PIDFILE
    fi
}

check_root()
{
    if [ "$(id -u)" != "0" ]; then
        echo "You must be root to start, stop and restart $NAME."
        exit 4
    fi
}

check_process()
{
    # Check if the process is already running. Ignore grep line.
    result=`ps aux | grep /opt/glassfish/modules/glassfish.jar | grep -v grep | wc -l`
}

case $1 in
    start)
        check_root
        check_process
        if [ "$result" = "1"  ]; then
            echo "$NAME is already running"
        else
            # Check if PID file exists and delete it
            if [ -e $PIDFILE ]; then
                rm -f $PIDFILE
            else
                do_start
            fi              
        fi
    ;;

    stop)
        check_root
        if [ -e $PIDFILE ]; then
            do_stop
        else
            echo "$NAME is not running"
        fi
    ;;

    restart)
        check_root
        echo "Restarting $NAME..."
        check_process
        if [ "$result" = "1"  ]; then
            do_stop
            echo "Starting $NAME..."
            do_start
        fi                  
    ;;

    status)
        if [ -e $PIDFILE ]; then
            echo "$NAME is running. PID $(cat $PIDFILE)"
        else
            echo "$NAME is not running"
        fi
    ;;


    *)
            # Show help
            echo "Usage: $SCRIPTNAME {start|status|stop|restart}" >&2
            exit 3
    ;;
esac

由于它位于 /etc/init.d/ 下,我不确定该脚本是否仍然需要 INIT INFO 部分。

现在可以像这样将其用作正常服务:

sudo service glassfish start

然后将其添加到 rc 启动中,它将在重启后启动。

sudo update-rc.d glassfish defaults

相关内容