If-then - Nested vs. blocks (Bash)
I don't think this is a design pattern, but it's a small thing I've noticed over the years: When you need to check for multiple conditions, it's usually easier to do so in blocks of 'loosely coupled' statements, rather than in one 'tightly integrated' nested if-then statements: The latter is so much more work to understand and use.
The case that I use here, is about evaluating different ways that this routine gets its only argument: Against which website (within an Apache server) should it execute?
Nested statements
The promise of these nested statements is, that it is very efficient and somehow natural:
############################################################################### # Initialisation ############################################################################### # # Welcome message ######################################## # echo ""; echo ""; echo "### wp_sr_up.sh()..." # 1. Process command line argument? ######################################## # # * $0: Name of the script # * $1: First argument, etc. # # if # # Check if command line argument has been provided # [ "$1" ] then # echo " Command line argument has been provided: $1" # # Check command line argument ######################################## # if [ -f "$1/wp-config.php" ] then # echo " Command line argument seems to point to a valid WordPress site" path_local="$1" else echo " File ${1}/wp-config.php not found. Exiting" exit fi else # echo " Executed without command line argument..." # # 2. Executed from the root of a site? ######################################## # if [ -f "./wp-config.php" ] then echo " PWD seems to be the the root of a WordPress site" path_local="$1" else # echo " Executed outside the root of a WordPress site..." # # 3. Global variable "$path" being used? ######################################## # # Does "$path" have content? # echo " Variable path: $path" # if [ "$path" ] then echo " Variable 'path' contains value: $path" # # Check for wp-config.php # if [ -f "$path/wp-config.php" ] then # # $path seems valid. Ask user for confirmation # echo " Path seems ok" read -p " Continue (y/n)? " continue # if [ "$continue" = "y" ] then # path_local="$1" # else # echo " Terminated by user" exit # fi else # echo " Variable 'path' has a value, but doesn't seem to point to a valid WordPress site" echo " Exiting." exit # fi else # echo " Variable path doesn't seem to contain any value" echo " Exiting." exit # fi fi fi
Hybrid
In stead of nested if-then-statements, it is now in three blocks, which some of them still contain a nested statement:
############################################################################### # Argument ############################################################################### # # Reset path_local ######################################## # path_local="" # 1. Command line argument? ######################################## # # * $0: Name of the script # * $1: First argument, etc. # if [ "$1" ] then # echo " Command line argument provided: $1" # if [ -f "$1/wp-config.php" ] then # echo " Command line argument seems to point to a valid WordPress site" path_local="$1" else echo " File ${1}/wp-config.php not found. Exiting" exit fi else # echo " No command line argument provided" # fi # 2. PWD is a WordPress site? ######################################## # if [[ ! "$path_local" ]] && [ -f "./wp-config.php" ] then # echo " PWD seems to be a WordPress site." # path_local="$1" # else # echo " PWD doesn't seem to be a WordPress site." # fi # 3. Global variable "$path" being used? ######################################## # if [[ ! "$path_local" ]] && [ "$path" ] then # echo " Global variable 'path' seems to have a value" # if [ -f "$path/wp-config.php" ] then # # $path seems valid. Ask user for confirmation # echo " Path seems ok" read -p " Continue (y/n)? " continue # if [ "$continue" = "y" ] then # path_local="$1" # else # echo " Terminated by user" exit # fi else # echo " Variable 'path' has a value, but doesn't seem to point to a valid WordPress site" echo " Exiting." exit # fi else # echo " Variable path doesn't seem to contain any value" echo " Exiting." exit # fi
Only blocks
Now without any nested if-then-statements (except for the third case, where user input is incorporated):
- Not every case is tested (and reported about by using
echo
, but it's much easier to read and to maintain - I think that's way more important - To my surprise, this is only 82 lines of code, compaired to 104 for the first example (which also reported much more extensively)
- BTW, I only now found some errors in the previous scripts.
############################################################################### # Argument ############################################################################### # # Reset path_local ######################################## # path_local="" # 1. Command line argument? ######################################## # # * $0: Name of the script # * $1: First argument, etc. # if [ "$1" ] && [ -f "$1/wp-config.php" ] then # echo " Command line argument provided: $1" echo " Command line argument seems to point to a valid WordPress site" path_local="$1" # fi # 2. PWD is a WordPress site? ######################################## # if [[ ! "$path_local" ]] && [ -f "./wp-config.php" ] then # echo " PWD seems to be a WordPress site." path_local="$PWD" # fi # 3. Global variable "$path" being used? ######################################## # if [[ ! "$path_local" ]] && [ "$path" ] && [ -f "$path/wp-config.php" ] then # echo " Global variable 'path' seems to point to a WordPress site" read -p " Continue (y/n)? " continue # if [ "$continue" = "y" ] then # path_local="$path" # else # echo " Terminated by user" # fi # fi # Still no value? → Exit ######################################## # if [[ ! "$path_local" ]] then # echo " No WordPress site found. Exiting" exit # fi # Got a value! ######################################## # echo " And the path is: $path_local"