Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

bash sequence: wait for output, then start next program

In my case I have to run openvpn before ssh'ing into a server, and the openvpn command echos out "Initialization Sequence Completed".

So, I want my script to setup the openvpn and then ssh in.

My question is: How do you execute a command in bash in the background and await it to echo "completed" before running another program?

My current way of doing this is having 2 terminal panes open, one running:

sudo openvpn --config FILE

and in the other I run:

ssh SERVER

once the the first terminal pane has shown me the "Initialization Sequence Completed" text.

like image 849
stilliard Avatar asked Jan 08 '14 16:01

stilliard


1 Answers

It seems like you want to run openvpn as a process in the background while processing its stdout in the foreground.

exec 3< <(sudo openvpn --config FILE)
sed '/Initialization Sequence Completed$/q' <&3 ; cat <&3 &
# VPN initialization is now complete and running in the background
ssh SERVER

Explanation

Let's break it into pieces:

  1. echo <(sudo openvpn --config FILE) will print out something like /dev/fd63
    • the <(..) runs openvpn in the background, and...
    • attaches its stdout to a file descriptor, which is printed out by echo
  2. exec 3< /dev/fd63
    • (where /dev/fd63 is the file descriptor printed from step 1)
    • this tells the shell to open the file descriptor (/dev/fd63) for reading, and...
    • make it available at the file descriptor 3
  3. sed '/Initialization Sequence Completed$/q' <&3
    • now we run sed in the foreground, but make it read from the file descriptor 3 we just opened
    • as soon as sed sees that the current line ends with "Initialization Sequence Completed", it quits (the /q part)
  4. cat <&3 &
    • openvpn will keep writing to file descriptor 3 and eventually block if nothing reads from it
    • to prevent that, we run cat in the background to read the rest of the output

The basic idea is to run openvpn in the background, but capture its output somewhere so that we can run a command in the foreground that will block until it reads the magic words, "Initialization Sequence Completed". The above code tries to do it without creating messy temporary files, but a simpler way might be just to use a temporary file.

like image 82
Michael Kropat Avatar answered Nov 09 '22 22:11

Michael Kropat