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.
command-1 && command-2 && command-3 && ... command-n
|
Example 25-1. Using an "and list" to test for command-line arguments
#!/bin/bash
# "and list"
if [ ! -z "$1" ] && echo "Argument #1 = $1" && [ ! -z "$2" ] && echo "Argument #2 = $2"
then
echo "At least 2 arguments passed to script."
# All the chained commands return true.
else
echo "Less than 2 arguments passed to script."
# At least one of the chained commands returns false.
fi
# Note that "if [ ! -z $1 ]" works, but its supposed equivalent,
# if [ -n $1 ] does not. However, quoting fixes this.
# if [ -n "$1" ] works. Careful!
# It is best to always quote tested variables.
# This accomplishes the same thing, using "pure" if/then statements.
if [ ! -z "$1" ]
then
echo "Argument #1 = $1"
fi
if [ ! -z "$2" ]
then
echo "Argument #2 = $2"
echo "At least 2 arguments passed to script."
else
echo "Less than 2 arguments passed to script."
fi
# It's longer and less elegant than using an "and list".
exit 0
|
Example 25-2. Another command-line arg test using an "and list"
#!/bin/bash
ARGS=1 # Number of arguments expected.
E_BADARGS=65 # Exit value if incorrect number of args passed.
test $# -ne $ARGS && echo "Usage: `basename $0` $ARGS argument(s)" && exit $E_BADARGS
# If condition-1 true (wrong number of args passed to script),
# then the rest of the line executes, and script terminates.
# Line below executes only if the above test fails.
echo "Correct number of arguments passed to this script."
exit 0
# To check exit value, do a "echo $?" after script termination.
|
Of course, an and list can also set variables to a default value.
arg1=$@ # Set $arg1 to command line arguments, if any.
[ -z "$arg1" ] && arg1=DEFAULT
# Set to DEFAULT if not specified on command line.
|
command-1 || command-2 || command-3 || ... command-n
|
Example 25-3. Using "or lists" in combination with an "and list"
#!/bin/bash
# delete.sh, not-so-cunning file deletion utility.
# Usage: delete filename
E_BADARGS=65
if [ -z "$1" ]
then
echo "Usage: `basename $0` filename"
exit $E_BADARGS # No arg? Bail out.
else
file=$1 # Set filename.
fi
[ ! -f "$file" ] && echo "File \"$file\" not found. \
Cowardly refusing to delete a nonexistent file."
# AND LIST, to give error message if file not present.
# Note echo message continued on to a second line with an escape.
[ ! -f "$file" ] || (rm -f $file; echo "File \"$file\" deleted.")
# OR LIST, to delete file if present.
# Note logic inversion above.
# AND LIST executes on true, OR LIST on false.
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.
false && true || echo false # false
# Same result as
( false && true ) || echo false # false
# But *not*
false && ( true || echo false ) # (nothing echoed)
# Note left-to-right grouping and evaluation of statements,
# since the logic operators "&&" and "||" have equal precedence.
# It's best to avoid such complexities, unless you know what you're doing.
# Thanks, S.C.
|
See Example A-8 and Example 7-4 for illustrations of using an and / or list to test variables.