| Advanced Bash-Scripting Guide: A complete guide to shell scripting, using Bash | ||
|---|---|---|
| Prev | Chapter 3. Tutorial / Reference | Next |
3.23. List Constructs
The "and list" and "or list" constructs provide a means of processing a number of commands consecutively. These can effectively replace complex nested if/then or even case statements.
- and list
Each command executes in turn provided that the previous command has given a return value of true (zero). At the first false (non-zero) return, the command chain terminates (the first command returning false is the last one to execute).1 command-1 && command-2 && command-3 && ... command-n
Example 3-146. Using an "and list" to test for command-line arguments
1 #!/bin/bash 2 3 # "and list" 4 5 if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] && echo "Argument #2 = $2" 6 then 7 echo "At least 2 arguments to script." 8 # All the chained commands return true. 9 else 10 echo "Less than 2 arguments to script." 11 # At least one of the chained commands returns false. 12 fi 13 # Note that "if [ ! -z $1 ]" works, but its supposed equivalent, 14 # if [ -n $1 ] does not. However, quoting fixes this. 15 # if [ -n "$1" ] works. Careful! 16 # It is best to always quote tested variables. 17 18 19 # This accomplishes the same thing, coded using "pure" if/then statements. 20 if [ ! -z "$1" ] 21 then 22 echo "Argument #1 = $1" 23 fi 24 if [ ! -z "$2" ] 25 then 26 echo "Argument #2 = $2" 27 echo "At least 2 arguments to script." 28 else 29 echo "Less than 2 arguments to script." 30 fi 31 # It's longer and less elegant than using an "and list". 32 33 34 exit 0
Example 3-147. Another command-line arg test using an "and list"
1 #!/bin/bash 2 3 ARGS=1 # Number of arguments expected. 4 E_BADARGS=65 # Exit value if incorrect number of args passed. 5 6 test $# -ne $ARGS && echo "Usage: `basename $0` $ARGS argument(s)" && exit $E_BADARGS 7 # If condition-1 true (wrong number of args passed to script), 8 # then the rest of the line executes, and script terminates. 9 10 # Line below executes only if the above test fails. 11 echo "Correct number of arguments passed to this script." 12 13 exit 0 14 15 # To check exit value, do a "echo $?" after script termination.
- or list
Each command executes in turn for as long as the previous command returns false. At the first true return, the command chain terminates (the first command returning true is the last one to execute). This is obviously the inverse of the "and list".1 command-1 || command-2 || command-3 || ... command-n
Example 3-148. Using "or lists" in combination with an "and list"
1 #!/bin/bash 2 3 # "Delete", not-so-cunning file deletion utility. 4 # Usage: delete filename 5 6 if [ -z "$1" ] 7 then 8 file=nothing 9 else 10 file=$1 11 fi 12 # Fetch file name (or "nothing") for deletion message. 13 14 15 [ ! -f "$1" ] && echo "$1 not found. Can't delete a nonexistent file." 16 # AND LIST, to give error message if file not present. 17 18 [ ! -f "$1" ] || ( rm -f $1; echo "$file deleted." ) 19 # OR LIST, to delete file if present. 20 # ( command1 ; command2 ) is, in effect, an AND LIST variant. 21 22 # Note logic inversion above. 23 # AND LIST executes on true, OR LIST on false. 24 25 [ ! -z "$1" ] || echo "Usage: `basename $0` filename" 26 # OR LIST, to give error message if no command line arg (file name). 27 28 exit 0

If the first command in an "or list" returns true, it will execute.
![]() | The exit status of an and list or an or list is the exit status of the last command executed. |
Clever combinations of "and" and "or" lists are possible, but the logic may easily become convoluted and require extensive debugging.
1 false && true || echo false # false 2 3 # Same result as 4 ( false && true ) || echo false # false 5 # But *not* 6 false && ( true || echo false ) # (nothing echoed) 7 8 # Note left-to-right grouping and evaluation of statements, 9 # since the logic operators "&&" and "||" have equal precedence. 10 11 # It's best to avoid such complexities, unless you know what you're doing. 12 13 # Thanks, S.C. |

