2

I'm using a shell script from the answer to this post to re-start a process if it exits. I have several processes that I need to start with this script, so I'm writing another script to launch them in order. I want to check that each process is launched successfully before continuing in the launch order. I've written a script similar to this.

#!/bin/sh

launch() {
    exec "$1" "$2" &!

    local pid="$(pidof $2)"
    echo "PID: $pid"

    if [ "$pid" == "" ]; do
            return 1
    done

    return 0
}

launch [looping-script.sh] [process-to-wrap]

exit 0

When I run this script with valid arguments for launch the script and process start and show up in ps output, but the value of $pid is blank and the function return 1. However, if I take the [looping-script.sh] argument out of the equation, like so.

#!/bin/sh

launch() {
    exec "$1" &!

    local pid="$(pidof $1)"
    echo "PID: $pid"

    if [ "$pid" == "" ]; do
            return 1
    done

    return 0
}

launch [process-to-wrap]

exit 0

Then $pid matches the value output by ps for the process and the function returns 0. Is there something incorrect about my call in the first script?

bash --version output if it's useful:

GNU bash, version 4.3.30(1)-release (arm-petalinux-linux-gnueabi)
Copyright (C) 2013 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
Community
  • 1
  • 1
OttPrime
  • 1,878
  • 1
  • 15
  • 24
  • 1
    What does `&!` mean? I've never seen that, and can't find it in the Bash manual. – Barmar Dec 22 '15 at 22:02
  • 1
    `pidof` may be running before the wrapper script has had time to start the process to wrap. Try adding `sleep 1` after you run the looping script. – Barmar Dec 22 '15 at 22:06
  • @Bamar I think that's it. I was way too deep into that thinking it was something weird about the exec command and the script I was using. If you want to post that as an answer, it's all yours. – OttPrime Dec 22 '15 at 22:12

2 Answers2

2

You're not allowing time for looping-script.sh to start process-to-wrap. Try adding a sleep command before checking for the PID.

exec "$1" "$2" &!
sleep 1
local pid="$(pidof $2)"
Barmar
  • 741,623
  • 53
  • 500
  • 612
2

Why use pidof to get the process ID of the monitored command? It will not do what you want if there happens to be more than one matching process. The shell can tell you what the PID was of the last subshell it started, e.g. to run a background pipeline:

exec "$@" &
local pid=$!
echo "PID: $pid"

Note also the "$@", which accommodates any number of arguments to the command you want to launch.

John Bollinger
  • 160,171
  • 8
  • 81
  • 157
  • By the way, I can't speak for yours, but my `bash` doesn't like the `!` appended to the `&`. – John Bollinger Dec 22 '15 at 22:30
  • @Barmar answered my specific question so I'm giving him the checkmark but I'll look into using `$!` for the process ID. I have other guards in place to prevent more than one instance of the process from running but thanks for the concern. The script above was more for illustration and isn't the actual production script. – OttPrime Dec 23 '15 at 13:01
  • Using `$!` in my case returns the PID of the `looping-script.sh` argument and not the PID of the `process-to-wrap` argument. That won't work for me, as I'm trying to ensure that the wrapped process is running before moving on. – OttPrime Dec 23 '15 at 13:23