Watch and Wait

Over the last 6 months I’ve become aware of two (new to me) commands (Kevin Closson pointed out that wait is actually a shell “builtin” command as opposed to any other type of command ;-)) that have been very useful: watch and wait. If you are not already familiar with them then I recommend you have a read, have a play and wait patiently for the first opportunity to use them.

There is no point in quoting the man pages here, so I’ll just give quick examples.

watch

In its simplest form: watch <command>

For example:

$ watch date

This displays the output below on screen, refreshing every 2 seconds (as stated in the top left):

Every 2.0s: date                                                     Sun Jul 24 21:15:37 2011

Sun 24 Jul 2011 21:15:37 BST

The example is clearly not very useful, but it demonstrates the functionality. The command I’ve been using most with watch is crsctl stat res ora.<db_name>.db -t , which is really nice for monitoring the state of the 8 instance RAC database running on your Exadata system[1] during patching or other activity that does more than its fair share of stopping and starting instances.

wait

My introduction to wait was over a few beers. I’d asked a friend how he was monitoring for the completion of multiple child processes run concurrently as part of something he’d previously described. It turned out he wasn’t monitoring for completion in a script, because he didn’t need to… However, for one of the scripts I’m currently working on I needed to wait for all the child processes to exit (and check their exit status) before proceeding. Fortunately another member of the group said:

Sounds like what you need is wait.

I’d never heard of wait, but it certainly sounded promising! I put together a very simple script to test that my interpretation of the man page was correct:

#!/bin/bash

myCommand () {
 echo "I am command $1, I will be \"working\" for $2 seconds and my exit status will be $3."
 sleep $2
 exit $3
}

echo The time is: $(date +%T)
myCommand 1 20 $1 &
myCommand 2 10 $2 &
echo The time is: $(date +%T)
echo "Waiting..."
wait %1
j1_exit=$?
wait %2
j2_exit=$?
if [[ $j1_exit -ne 0 ]] || [[ $j2_exit -ne 0 ]]; then
 echo "At least one of the child processes didn't finish... Exiting!"
 echo "Child process 1 exited with $j1_exit"
 echo "Child process 2 exited with $j2_exit"
else
 echo "Completed with no errors from child processes."
fi
echo The time is: $(date +%T)

Running the command with a selection of input parameters to control the exit status of the child processes:

martin$ ./wait.sh 0 0
The time is: 21:19:04
I am command 1, I will be "working" for 20 seconds and my exit status will be 0.
I am command 2, I will be "working" for 10 seconds and my exit status will be 0.
The time is: 21:19:04
Waiting...
Completed with no errors from child processes.
The time is: 21:19:24
martin$ ./wait.sh 1 0
The time is: 21:19:27
I am command 1, I will be "working" for 20 seconds and my exit status will be 1.
I am command 2, I will be "working" for 10 seconds and my exit status will be 0.
The time is: 21:19:27
Waiting...
At least one of the child processes didn't finish... Exiting!
Child process 1 exited with 1
Child process 2 exited with 0
The time is: 21:19:47
martin$ ./wait.sh 0 1
The time is: 21:19:52
I am command 1, I will be "working" for 20 seconds and my exit status will be 0.
I am command 2, I will be "working" for 10 seconds and my exit status will be 1.
The time is: 21:19:52
Waiting...
At least one of the child processes didn't finish... Exiting!
Child process 1 exited with 0
Child process 2 exited with 1
The time is: 21:20:12
martin$ ./wait.sh 1 1
The time is: 21:20:16
I am command 1, I will be "working" for 20 seconds and my exit status will be 1.
I am command 2, I will be "working" for 10 seconds and my exit status will be 1.
The time is: 21:20:16
Waiting...
At least one of the child processes didn't finish... Exiting!
Child process 1 exited with 1
Child process 2 exited with 1
The time is: 21:20:36

I’m sure it seems that I’m easily pleased, but this gives me the functionality to easily create multi-threaded shell scripts, which isn’t something I’ve needed, or at least realised would be useful to me, in the past.
_________________________________________________
1. Other multi-instance database platforms are available 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s