Search code examples
linuxbashraspberry-piraspbian

Wait for command to finish / window to close in Bash


I have an application that should work 24/7 on a Raspberry Pi. To ensure that, I'm trying to write a bash script that will run on bootup, execute my main application , and in case of a failure (bugs, exceptions, etc.) execute it again.

This is my script :

#!/bin/bash

while true
do
    lxterminal --title="mytitle" --geometry=200x200 -e "./myapplication"
done

As expected, this opens infinite amount of terminal windows. Then I have tried :

#!/bin/bash

while true
do
    lxterminal --title="mytitle" --geometry=200x200 -e "./myapplication" &
    PID=$!
    wait $PID
done

This one also did not work like I wanted, it waits for the lxterminal process to finish, but that is not what I expect. Instead, I want my script to wait for lxterminal window to close, and continue with the loop.

Is that possible? Any suggestions?


Solution

  • In this case, your script is behaving properly. By doing this:

    lxterminal --title="mytitle" --geometry=200x200 -e "./myapplication" &
    PID=$!
    wait $PID
    

    Wait will use the PID of the last command used (lxterminal). However, you are interested in child process which would be the PID of ./myapplication running itself. Basically, lxterminal will have its own PID and as parent, it will launch your script and it will create a new process with its new PID (child).

    So the question would be, how to retrieve the PID child process given the parent child?

    In your case, we can use next command.

    ps --ppid $PID

    Which will give such output.

    ps --ppid 11944
      PID TTY          TIME CMD
    11945 pts/1    00:00:00 sleep
    

    Then, with some help, we can retrieve only the child PID.

    ps --ppid 11944 | tail -1 | cut -f1 -d" "
    11945
    

    So finally, in your script, you can add new variable containing child process.

    #!/bin/bash
    
    while true
    do
        lxterminal --title="mytitle" --geometry=200x200 -e "./myapplication" &
        PID=$!
        CPID=ps --ppid $PID | tail -1 | cut -f1 -d" "
        wait $CPID
    done
    

    I did not really try it in your case, as I don't have same scenario than yours, but I believe it should work, if not, there might be some hints in this answer which might help you to find proper solution to your problem.