diff --git a/MAC/APL/APLCommon/src/swlevel b/MAC/APL/APLCommon/src/swlevel index cb601b78b9a84b97c91bed89571fe8b146111978..1a554e354ac3aabcb9e82ba146070555eeca3ec7 100755 --- a/MAC/APL/APLCommon/src/swlevel +++ b/MAC/APL/APLCommon/src/swlevel @@ -47,10 +47,47 @@ LEVELTABLE=${ETCDIR}/swlevel.conf function getpid { PROGRAM="$1" - # use "pgrep -f" to get the PID of scripts. - # only use this as a fall-back when "pgrep" itself returns nothing, - # since "pgrep -f" returns false positives for non-scripts. - pgrep $PROGRAM || pgrep -f $PROGRAM + # Linux tools seem to fail here, since we want to match both + # programs and scripts on name: + # + # pgrep $PROGRAM : Only matches executables, not scripts. + # pgrep -f $PROGRAM : Matches the program anywhere in the command line, is way too broad + # pidof : Only matches executables, not scripts. + # pidof -x : Cannot match scripts started with #!/usr/bin/env as that changes the executable name used + +ps --no-headers -eo pid,cmd | python3 -c ' +import sys +from os.path import basename + +if len(sys.argv) < 2: + print("Usage: ps --no-headers -eo pid,cmd | %s progname" % sys.argv[0]) + sys.exit(1) + +PROG=sys.argv[1] + +# name of commands that are actually script interpreters +SCRIPT_INTERPRETERS=["python","python2","python3","bash","sh","tcsh"] + +pids = [] + +for l in sys.stdin.readlines(): + pid, cmdline = l.split(None, 1) + + # all command-line arguments, but drop any that start with a DASH (except if it is the program name) + cmdargs = [a for nr,a in enumerate(cmdline.split()) if nr == 0 or not a.startswith("-")] + + # PROG is invoked directly + if basename(cmdargs[0]) == PROG: + pids += [pid] + # PROG is the first command-line argument to a script + elif len(cmdargs) > 1 and basename(cmdargs[0]) in SCRIPT_INTERPRETERS and basename(cmdargs[1]) == PROG: + pids += [pid] + +if pids: + print(" ".join(pids)) + +sys.exit(0 if pids else 1) +' "$PROGRAM" } # Counter to indicate if 48V reset has been attempted @@ -308,7 +345,7 @@ start_prog() fi if [ "$prog" = "TBBDriver" ]; then # Check if RSPDriver is already running; if not, do not start either! - getpid RSPDriver 1>/dev/null 2>&1 + $PIDOF RSPDriver 1>/dev/null 2>&1 if [ $? -ne 0 ]; then echo "RSPDriver not running, so not starting TBBDriver either" exit @@ -548,7 +585,7 @@ goto_level() # set rcumode to 0 (power save) when entering level 1 if [ ${newlevel} -le 1 ]; then if [ ${curlevel} -ge 2 ]; then - getpid RSPDriver 1>/dev/null 2>&1 + $PIDOF RSPDriver 1>/dev/null 2>&1 if [ $? -eq 0 ]; then status_1=`( timeout 2 $BINDIR/rspctl --version | grep "0.0" ) >& /dev/null; echo $?` status_2=`( timeout 2 $BINDIR/rspctl --status | grep "PCB" ) >& /dev/null; echo $?`