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.
1 command-1 && command-2 && command-3 && ... command-n |
Example 25-1. Using an "and list" to test for command-line arguments
1 #!/bin/bash 2 # "and list" 3 4 if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] && echo "Argument #2 = $2" 5 then 6 echo "At least 2 arguments passed to script." 7 # All the chained commands return true. 8 else 9 echo "Less than 2 arguments passed to script." 10 # At least one of the chained commands returns false. 11 fi 12 # Note that "if [ ! -z $1 ]" works, but its supposed equivalent, 13 # if [ -n $1 ] does not. However, quoting fixes this. 14 # if [ -n "$1" ] works. Careful! 15 # It is best to always quote tested variables. 16 17 18 # This accomplishes the same thing, using "pure" if/then statements. 19 if [ ! -z "$1" ] 20 then 21 echo "Argument #1 = $1" 22 fi 23 if [ ! -z "$2" ] 24 then 25 echo "Argument #2 = $2" 26 echo "At least 2 arguments passed to script." 27 else 28 echo "Less than 2 arguments passed to script." 29 fi 30 # It's longer and less elegant than using an "and list". 31 32 33 exit 0 |
Example 25-2. 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. |
Of course, an and list can also set variables to a default value.
1 arg1=$@ # Set $arg1 to command line arguments, if any. 2 3 [ -z "$arg1" ] && arg1=DEFAULT 4 # Set to DEFAULT if not specified on command line. |
1 command-1 || command-2 || command-3 || ... command-n |
Example 25-3. Using "or lists" in combination with an "and list"
1 #!/bin/bash 2 3 # delete.sh, not-so-cunning file deletion utility. 4 # Usage: delete filename 5 6 E_BADARGS=65 7 8 if [ -z "$1" ] 9 then 10 echo "Usage: `basename $0` filename" 11 exit $E_BADARGS # No arg? Bail out. 12 else 13 file=$1 # Set filename. 14 fi 15 16 17 [ ! -f "$file" ] && echo "File \"$file\" not found. \ 18 Cowardly refusing to delete a nonexistent file." 19 # AND LIST, to give error message if file not present. 20 # Note echo message continued on to a second line with an escape. 21 22 [ ! -f "$file" ] || (rm -f $file; echo "File \"$file\" deleted.") 23 # OR LIST, to delete file if present. 24 25 # Note logic inversion above. 26 # AND LIST executes on true, OR LIST on false. 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. |
See Example A-8 and Example 7-4 for illustrations of using an and / or list to test variables.