#!/bin/bash # chkconfig: 2345 98 2 # description: shellbox service for spawning programs . /etc/profile export PATH=$PATH:/usr/local/bin # AD84: export HOSTNAME=$(hostname -s) # AD84: added if [ -f /usr/local/bin/getIocBootEnv ] then . /usr/local/bin/getIocBootEnv #echo "" #echo "shellbox: IOC=$IOC" #echo "shellbox: FACILITY=$FACILITY" #echo "shellbox: ROOTFSSERVERIP=$ROOTFSSERVERIP" #echo "shellbox: BOOTPC=$BOOTPC" #echo "shellbox: CMDLINE_HOST=$CMDLINE_HOST" #echo "shellbox: CMDLINE_ETH=$CMDLINE_ETH" #echo "shellbox: BOOTIF_BCAST=$BOOTIF_BCAST" #echo "shellbox: BOOTIF_IP=$BOOTIF_IP" #echo "" fi if [ "$IOC" == "" ] then HOSTNAME=$(hostname -s) else HOSTNAME=$IOC fi export HOSTNAME # AD84: end added exe=/usr/local/bin/procServ options="-k ^X --killsig 15 -x ^D -i ^C --allow -c" prog=shellbox params= conf=/etc/shellbox.conf logdir=/var/log/$prog shells=/var/run/$prog fail () { echo $@ exit 1 } echo_failure () { echo " [failed]" } checkpid () { [ -d /proc/$PID ] } launch () { [ -f /ioc/${HOSTNAME}/DoNotStartEpics ] && fail "Not starting EPICS because /ioc/${HOSTNAME}/DoNotStartEpics exists" if [ "$1" = "-reload" ] then reload=YES shift fi temp=$(mktemp -p $(dirname $shells)) || fail "can't create temporary file" while read PORT USER DIR COMMAND ARGS do # check for empty lines and comments [[ $PORT == "" || $PORT == \#* ]] && continue # AD84: added DIR=${DIR//_IOCNAME_/$HOSTNAME} ARGS=${ARGS//_IOCNAME_/$HOSTNAME} # AD84: end added # check if already started shell is still alive if LINE=$(grep "$PORT $USER $DIR $COMMAND $ARGS" $shells 2> /dev/null) then PID=${LINE%% *} if checkpid $PID then if [ -z "$reload" ] && [ -z "$*" ] || echo "$*" | grep -qE "(^|[[:space:]])$PORT([[:space:]]|$)" then echo "Already running: $PORT $USER $DIR $COMMAND $ARGS" fi echo "$LINE" >> $temp continue fi fi # check if we have to start all shells or only this PORT [ "$*" ] && echo "$*" | grep -qvE "(^|[[:space:]])$PORT([[:space:]]|$)" && continue if [ -n "$logdir" ] then [ -d $logdir ] || mkdir -m 777 $logdir LOG=$logdir/$PORT rm -f $LOG else LOG=/dev/null fi # start shellbox as other user echo -n Starting: $PORT $USER $DIR $COMMAND $ARGS if /usr/bin/sudo -E true 2> /dev/null then SUDO="/usr/bin/sudo -H -u $USER SHELLBOX=$HOSTNAME:$PORT" elif /usr/bin/sudo true 2> /dev/null then SUDO="/usr/bin/sudo -H -u $USER" fi export SHELLBOX=$HOSTNAME:$PORT pidfile=/var/run/procServ-$PORT.pid rm -f $pidfile L=/tmp/$SHELLBOX.log mknod -m 666 $L p 2>/dev/null logger -p local0.info -t shellbox["$PORT"] -f $L & $exe -p $pidfile $options $DIR $params -L $L $PORT $SUDO $(which $COMMAND) $ARGS >> $LOG 2>&1 < /dev/null # check if starting worked or failed usleep 100000 if [ -e $pidfile ] then PID=$(<$pidfile) echo "$PID $PORT $USER $DIR $COMMAND $ARGS" >> $temp echo else echo_failure echo cat $LOG fi done < $conf mv $temp $shells chmod 0644 $shells } start () { [ -r $conf ] || fail "$conf not readable" [ -x $exe ] || fail "$exe is not executable" launch $* touch /var/lock/subsys/$prog } stopshell() { PID=$1 PORT=$2 shift echo -n Stopping: $* kill $PID 2> /dev/null || echo_failure echo if [ $logdir ] then echo -e "\n**** stopped ****" >> $logdir/$PORT fi } stop () { # anything to stop? if [ ! -r $shells ] then echo "$prog: No shells started." exit 0 fi if [ -z "$1" ] then # kill all shellboxes while read PID PORT ARGS do stopshell $PID $PORT $ARGS done < $shells rm -f $shells rm -f /var/lock/subsys/$prog else # kill only selected shellboxes temp=$(mktemp -p $(dirname $shells)) || fail "can't create temporary file" while read PID PORT ARGS do echo "$*" | grep -qE "(^|[[:space:]])$PORT([[:space:]]|$)" && stopshell $PID $PORT $ARGS || echo "$PID $PORT $ARGS" >> $temp done < $shells mv $temp $shells chmod 0644 $shells fi } reload () { echo "Reloading $conf: " [ -r $conf ] || fail "not readable" # anything to stop? if [ -r $shells ] then #first kill all shells that are not configured any more temp=$(mktemp -p $(dirname $shells)) || fail "can't create temporary file" while read PID LINE do while read PORT USER DIR COMMAND ARGS do # AD84: added DIR=${DIR//_IOCNAME_/$HOSTNAME} ARGS=${ARGS//_IOCNAME_/$HOSTNAME} # AD84: end added if [ "$PORT $USER $DIR $COMMAND $ARGS" = "$LINE" ] then echo "Keeping: $LINE" echo "$PID $LINE" >> $temp continue 2 fi done < $conf stopshell $PID $PORT $LINE done < $shells mv $temp $shells chmod 0644 $shells fi #now start all new shells sleep 2 launch -reload } status () { [ -r $conf ] || fail "$conf not readable" if [ "$1" = "-log" ] then log=YES shift fi echo -e "pid\tport\tuser\tdir\t\t\tcommand" while read PORT USER DIR COMMAND ARGS do # check for empty lines and comments [[ $PORT == "" || $PORT == \#* ]] && continue # AD84: added DIR=${DIR//_IOCNAME_/$HOSTNAME} ARGS=${ARGS//_IOCNAME_/$HOSTNAME} # AD84: end added # check if we have to report all shells [ "$*" ] && echo "$*" | grep -qvE "(^|[[:space:]])$PORT([[:space:]]|$)" && continue if [ "$logdir" -a "$log" ] then echo "-------------------------------------------------------------------" fi if LINE=$(grep "$PORT $USER $DIR $COMMAND $ARGS" $shells 2> /dev/null) then PID=${LINE%% *} if checkpid $PID then echo -n $PID else $SETCOLOR_FAILURE echo -n DEAD $SETCOLOR_NORMAL fi else $SETCOLOR_FAILURE echo -n STOPPED $SETCOLOR_NORMAL fi echo -e "\t$PORT\t$USER\t$DIR\t$COMMAND $ARGS" if [ "$logdir" -a "$log" ] then grep '\*\*\*\*' $logdir/$PORT 2>/dev/null fi done < $conf } CMD=$1 shift case "$CMD" in (start) start $*;; (stop) stop $*;; (restart) stop $*; sleep 2; start $*;; # kill all shells, then start again (reread|reload) reload $*;; # reload shellbox.conf without killing too much (status) status $*;; (*) echo "Usage: $0 {start [ports]|stop [ports]|restart [ports]|reload|status [-log] [ports]}" ;; esac