我尝试为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。
为了理解,我看了这些帖子:
帕特里克的回答
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