Leveling up your bash
Henrik Holst
Ethology researcher spending most of his time deep down in the comments section searching for intelligent life
One quite common use case is to wait for stuff to be completed. Suppose there are a few tasks we can execute
task1
task2
This will execute task1 to completion and then execute task2 and run that to completion.
We can run these tasks concurrently
task1 &
task2 &
And we can also wait for them to complete
wait
However, did you know that you can wait for either one of these tasks?
wait -n
This will wait for one task to complete.
Here is the great thing about this.
We can get the exit code from the task through the $? variable.
Use case. Waiting for a Kubernetes job to complete.
A Kubernetes job can complete in two ways. It can either succeed, or it can fail. kubectl allows us to wait for a job to complete, but we can only wait for it to either succeed or to fail. But not either.
Thanks to the bash shell we can work around that quite easily.
s() (
kubectl wait --for=condition=succeeded job/myjob --timeout=300s
exit 0
)
f() (
kubectl wait --for=condition=failed job/myjob --timeout=300s
exit 1
)
We can now wait for these two states concurrently
s &
f &
# enabling set -e will make the shell script abort with an error if the wait returns with an error, meaning f completed first.
set -e
wait -n
Useful right?
You can also build conditional logic with the exit codes. Suppose task3 should only run if task2 completes first and task2 returns exit code 1
task1 &
task2 &
if wait -n
then
task3
fi
Well, there are a million use cases and things that can be built using bash process management like this. Hopefully you have learned a new tool that you can start using!