Мой вариант скриптов начального запуска процессов. За основу взял идею djet
rc.inslug:
PHP Code:
#!/bin/sh
# Start/stop all init scripts in /opt/etc/init.d including symlinks
# starting them in numerical order and
# stopping them in reverse numerical order
if [ $# = 0 ]; then
printf "Usage: $0 {start|stop|restart}\n" >&2
exit 1
fi
ACTION=$1
DAEMONSDIR="`/usr/bin/dirname $0`/"
[ $ACTION = stop -o $ACTION = restart ] && ORDER="-r"
DAEMONS=`/opt/bin/find $DAEMONSDIR -perm '-u+x' -name 'S??*' | sort $ORDER`
for i in $DAEMONS; do
# Ignore dangling symlinks (if any).
[ ! -f "$i" ] && continue
case "$i" in
*.sh )
(
# Source shell script for speed.
trap - INT QUIT TSTP
set $ACTION
. $i
)
;;
*)
# No sh extension, so fork subprocess.
$i $ACTION
;;
esac
done
rc.func:
PHP Code:
#!/bin/sh
ansi_red="\033[1;31m";
ansi_green="\033[1;32m";
ansi_yellow="\033[1;33m";
ansi_white="\033[1;37m";
ansi_blue="\033[1;34m";
ansi_bell="\007";
ansi_blink="\033[5m";
ansi_std="\033[m";
ansi_rev="\033[7m";
ansi_ul="\033[4m";
PrintMsg() {
case "$2" in
1) msgtext=${ansi_green}${1}${ansi_std};;
2) msgtext=${ansi_yellow}${1}${ansi_std};;
3) msgtext=${ansi_red}${1}${ansi_std};;
*) msgtext=${1};;
esac
echo -e -n "$msgtext"
}
# Check if $pid are running
checkpid() {
while [ -n "$1" ]; do
[ -d /proc/$1 ] && return 0
shift
done
return 1
}
#
WaitUntilRun() {
COUNTER=0; LIMIT=10
while checkpid $1 && [ "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
}
#
WaitUntilDown() {
proc=$1 ; [ -z "$proc" ] && proc=$PROC
COUNTER=0
LIMIT=10
while [ -z "`pidof $proc`" -a "$COUNTER" -le "$LIMIT" ]; do
sleep 1s;
COUNTER=`expr $COUNTER + 1`
done
}
# A function to find the pid of a program.
pidofproc() {
# Test syntax.
if [ "$#" = 0 ] ; then
echo "Usage: pidofproc {program}"
return 1
fi
pid=0
proc="`basename $1`"
if [ -n "$PIDFILE" ] && [ -f $PIDFILE ] ; then
pid=`cat $PIDFILE`
elif [ -f /var/run/${proc}.pid ] ; then
pid=`cat /var/run/${proc}.pid`
fi
if [ -n "$pid" ] && [ -d /proc/$pid ] ; then
echo $pid
return 0
fi
# Next try "pidof"
pid=`pidof $1` || pid=`pidof $proc`
echo $pid
return 0
}
#
start() {
res=0
# Test syntax.
if [ "$#" = 0 ] ; then
echo "Usage: start {program} [arguments] [prefix command]"
return 1
fi
proc="`basename $1`"
PrintMsg "Starting $proc... "
pid=`pidofproc $1`
[ -n "$pid" ] && { PrintMsg "already running. id:$pid\n" 2; return 255;}
if [ "$#" = 3 ]; then
$3 $1 $2 2>&1 | /usr/bin/logger -t $proc
else
$1 $2 2>&1 | /usr/bin/logger -t $proc
fi
#$1 $2 > /dev/null 2>&1
WaitUntilDown $proc
if [ -n "`pidof $proc`" ]; then
PrintMsg "done.\n" 1
logger -t $proc "started"
res=0
else
PrintMsg "failed.\n" 3 ; res=1
fi
return $res
}
#
stop() {
res=0
# Test syntax.
if [ "$#" = 0 ] ; then
echo "Usage: stop {program} [signal]"
return 1
fi
proc="`basename $1`"
# Find pid.
pid=`pidofproc $1`
# check for second arg to be kill level
killlevel="$2"
str="Shutting down $proc... "
[ -n "$killlevel" ] && str="Send signal $killlevel to $proc... "
PrintMsg "$str"
# Kill it.
if [ -z "$pid" ]; then
PrintMsg "already down.\n" 2 ; return 255
fi
if [ -z "$killlevel" ] ; then
# TERM first, then KILL if not dead
kill -TERM $pid
usleep 100000
if checkpid $pid && sleep 1 &&
checkpid $pid && sleep 3 &&
checkpid $pid ; then
kill -KILL $pid
usleep 100000
fi
# use specified level only
else
kill $killlevel $pid
fi
WaitUntilRun $pid
if checkpid $pid >/dev/null 2>&1; then
PrintMsg "failed.\n" 3 ; res=1
else
PrintMsg "done.\n" 1 ; res=0
logger -t $proc "stopped"
fi
return $res
}
В этом варианте в скриптах запуска S* просто используются функции из rc.func.
Например,
S99dc (для microdc2):
PHP Code:
#!/bin/sh
. /opt/etc/init.d/rc.func
PROC=microdc2
DESC="$PROC"
PIDFILE=""
DAEMON="/opt/bin/$PROC"
ARGS="-c /opt/etc/microdc2/dc.conf"
PREFIX="/opt/bin/screen -dmS microdc"
CONFDIR=""
# installation check
if [ ! -x $DAEMON ]; then
echo "$DAEMON is not installed"
exit 1
fi
#microdc2 features
OLDHOME=$HOME
export HOME="/opt/var/microdc"
export LANG="ru_RU.UTF-8"
case "$1" in
start)
start "$DAEMON" "$ARGS" "$PREFIX"
res=$?
;;
stop)
stop $DAEMON
res=$?
;;
restart|force-reload)
stop $DAEMON
start "$DAEMON" "$ARGS" "$PREFIX"
res=$?
;;
*)
echo "Usage: $0 {start|stop|restart}" ; exit 1
;;
esac
export HOME=$OLDHOME
exit $res
При специфических особенностях запуска/останова сервиса в скриптах S* дописываются свои функции. Например, при остановке xinetd, нужно остановить также и сервера.
S10xinetd.sh:
PHP Code:
#!/bin/sh
. /opt/etc/init.d/rc.func
PROC=xinetd
DESC="xinetd"
PIDFILE="/var/run/xinetd.pid"
DAEMON="/opt/sbin/$PROC"
ARGS="-f /opt/etc/xinetd.conf -pidfile $PIDFILE"
CONFDIR="/opt/etc/xinetd.d/"
#
xinetd_stop() {
stop $DAEMON -SIGTERM
res=$?
for i in ${CONFDIR}* ; do
if [ -n "`grep "^[[:space:]]*disable[[:space:]]*=[[:space:]]*no" ${i}`" ] ; then
for j in `awk -F= '/^[[:space:]]*server[[:space:]]*=[[:space:]]*.*/{ print $2 }' ${i} | sort -u`; do
d="`basename $j`"
[ -n "`pidof $d`" ] || continue
stop $j
res=$?
done
fi
done
return $res
}
#
xinetd_reconfig() {
PrintMsg "Reconfigure $PROC... "
pid=`pidofproc $DAEMON`
[ -z "$pid" ] || { PrintMsg "not running.\n" 3 ; return 255;}
kill -SIGHUP $pid
sleep 1
if [ -d /proc/$pid ]; then
PrintMsg "done.\n" 1
logger -t $PROC "reconfigured"
return 0
else
PrintMsg "failed.\n" 3 ; return 1
fi
}
# installation check
if [ ! -x $DAEMON ]; then
echo "$DAEMON is not installed"
exit 1
fi
case "$1" in
start)
start "$DAEMON" "$ARGS" ; res=$?
;;
stop)
xinetd_stop ; res=$?
;;
reload|reconfig)
xinetd_reconfig ; res=$?
;;
restart|force-reload)
xinetd_stop ; res=$?
start "$DAEMON" "$ARGS"
;;
*)
echo "Usage: $0 {start|stop|reconfig|restart}" ; res=1
;;
esac
exit $res
Ну и до кучи
S10cron (для встроенного crond):
PHP Code:
#!/bin/sh
. /etc/init.d/rc.func
PROC=crond
DESC="$PROC"
PIDFILE=""
DAEMON="/usr/sbin/$PROC"
CONFDIR="/etc/crontabs/"
ARGS="-L /var/log/cron -c $CONFDIR"
crond_reconfig() {
PrintMsg "Reconfigure $PROC... "
pid=`pidofproc $DAEMON`
[ -z "$pid" ] || { PrintMsg "not running.\n" 3 ; return 255;}
echo "admin" >> ${CONFDIR}cron.update
sleep 1
if [ -d /proc/$pid ]; then
PrintMsg "done.\n" 1
logger -t $PROC "reconfigured"
return 0
else
PrintMsg "failed.\n" 3 ; return 1
fi
}
case "$1" in
start)
start "$DAEMON" "$ARGS"
res=$?
;;
stop)
stop "$DAEMON"
res=$?
;;
reload|reconfig)
crond_reconfig ; res=$?
;;
restart|force-reload)
stop "$DAEMON"
start "$DAEMON" "$ARGS"
res=$?
;;
*)
echo "Usage: $0 {start|stop|reconfig|restart}" ; exit 1
;;
esac
exit $res