I am new to bash scripting.
In my quest to pick it up, I begin to heartily appreciate chaining operators. With the help of chaining operators, I may not need if
conditional check in bash as often as other programming languages, i.e. Java or PHP.
Furthermore, to my surprise, lesser if
does not degrade the expressiveness of the script. Instead, it is more elegant and concise once I understand the quirk of it.
Let's see what do I mean by looking at the following example.
I need to write a bash script that make sure at any instance of time there is only a maximum of 10 certain files in a directory.
My first version of the script goes like this:
#!/bin/bash
set -u
##### Variable declaration #####
MY_DIR=~/rotateLog
MAX_FILE_COUNT=10
##### Method definition #####
_delete_oldest_file() {
ls -1tr $MY_DIR/temp.log.* | head -1 | xargs rm -f
}
##### Main #####
while true
do
FILE_COUNT=`ls -1tr $MY_DIR/temp.log.* | wc -l`
if [ $FILE_COUNT -gt $MAX_FILE_COUNT ]; then
_delete_oldest_file
fi
done
Program flow is pretty straight forward, described below:
- Check current file count in the directory
- Remove the oldest file from directory if there is more than what is needed
if
conditional check is always the de facto approach to tackle any sort of decision making problem. This script is okay.
Then, as I learn about chaining operators, i.e. &&
, ||
, ;
, etc, which are used to chain commands together, I think the script could be rewritten in a more concise manner. Let's focus on &&
for the moment being.
&&
is used to chain commands together, such that the next commands is run if and only if the preceding command exited without error (exit code of 0
).
Coupled with the fact that bash numeric comparison operators observe following behavior:
If numeric comparison is satisfied, exit code shall be 0
. Else, exit code shall be 1
. To illustrate:
$ [ 1 -gt 10 ]; echo $?
1
$ [ 11 -gt 10 ]; echo $?
0
Therefore, the original script could be revised to:
while true
do
FILE_COUNT=`ls -1tr $MY_DIR/temp.log.* | wc -l`
[ $FILE_COUNT -gt $MAX_FILE_COUNT ] && _delete_oldest_file
done
This is especially helpful if I have a flow involving many steps. Let's consider I have a 3 steps flow such that:
- Run
_do_A()
- Run
_do_B()
if_do_A()
is successfully executed - Run
_do_C()
if_do_B()
failed to execute
Without the help of chaining operators, I likely need 3 if
checking to deliver the flow. But with the help of chaining operators:
_do_A() && _do_B() || _do_C()
Elegant. Isn't it? 😎
Now, let's imagine we have a 10 steps flow. Isn't that chaining operators a life savior?
Top comments (0)