|
Softpanorama |
May the source be with you, but remember the KISS principle ;-)
|
| Advanced navigation | |||||
| if statements | Loops in Shell | case | select | Pipes in Loops | |
| Arithmetic expressions | Comparison operators | BASH Debugging | Shell history | Etc |
Shell case statement is similar to those in Pascal and switch statement in C. It can be used to test simple values like integers and characters.
BASH's case construct lets you test strings against patterns that can contain wildcard characters. Like its conventional language counterparts, case lets you express a series of if-then-else statements in a more concise way.
The syntax of case is as follows:
case expression in
pattern1 )
statements ;;
pattern2 )
statements ;;
...
esac
Any of the patterns can actually be several patterns separated by pipe characters (|). If expression matches one of the patterns, its corresponding statements are executed. If there are several patterns separated by pipe characters, the expression can match any of them in order for the associated statements to be run. The patterns are checked in order until a match is found; if none is found, nothing happens.
For example:
for filename in $*; do
case $filename in
*.c )
objname=${filename%.c}.o
ccom $filename $objname ;;
*.s )
objname=${filename%.s}.o
as $filename $objname ;;
*.o ) ;;
* )
print "error: $filename is not a source or object file."
return 1 ;;
esac
done
The final case is *, which is a catchall for whatever
didn't match the other cases. (In fact, a * case is
analogous to a default case in C and an otherwise case in some Pascal-derived
languages.)
Another example:
case "${x##*.}" in
gz)
gzunpack ${SROOT}/${x}
;;
bz2)
bz2unpack ${SROOT}/${x}
;;
*)
echo "Archive format not recognized."
exit
;;
esac
Above, bash first expands "${x##*.}". In the code, "$x" is the name of a file, and "${x##.*}" has the effect of stripping all text except that following the last period in the filename. Then, bash compares the resultant string against the values listed to the left of the ")"s. In this case, "${x##.*}" gets compared against "gz", then "bz2" and finally "*". If "${x##.*}" matches any of these strings or patterns, the lines immediately following the ")" are executed, up until the ";;", at which point bash continues executing lines after the terminating "esac". If no patterns or strings are matched, no lines of code are executed; however, in this particular code snippet, at least one block of code will execute, because the "*" pattern will catch everything that didn't match "gz" or "bz2".
#!/bin/bash a=4 b=5 # Here "a" and "b" can be treated either as integers or strings. # There is some blurring between the arithmetic and string comparisons, #+ since Bash variables are not strongly typed. # Bash permits integer operations and comparisons on variables #+ whose value consists of all-integer characters. # Caution advised. if [ "$a" -ne "$b" ] then echo "$a is not equal to $b" echo "(arithmetic comparison)" fi echo if [ "$a" != "$b" ] then echo "$a is not equal to $b." echo "(string comparison)" fi # In this instance, both "-ne" and "!=" work. echo exit 0
#!/bin/bash
# str-test.sh: Testing null strings and unquoted strings,
# but not strings and sealing wax, not to mention cabbages and kings...
# Using if [ ... ]
# If a string has not been initialized, it has no defined value.
# This state is called "null" (not the same as zero).
if [ -n $string1 ] # $string1 has not been declared or initialized.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
# Wrong result.
# Shows $string1 as not null, although it was not initialized.
echo
# Lets try it again.
if [ -n "$string1" ] # This time, $string1 is quoted.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi # Quote strings within test brackets!
echo
if [ $string1 ] # This time, $string1 stands naked.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
# This works fine.
# The [ ] test operator alone detects whether the string is null.
# However it is good practice to quote it ("$string1").
#
# As Stephane Chazelas points out,
# if [ $string 1 ] has one argument, "]"
# if [ "$string 1" ] has two arguments, the empty "$string1" and "]"
echo
string1=initialized
if [ $string1 ] # Again, $string1 stands naked.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
# Again, gives correct result.
# Still, it is better to quote it ("$string1"), because...
string1="a = b"
if [ $string1 ] # Again, $string1 stands naked.
then
echo "String \"string1\" is not null."
else
echo "String \"string1\" is null."
fi
# Not quoting "$string1" now gives wrong result!
exit 0
# Also, thank you, Florian Wisser, for the "heads-up".
#!/bin/bash
#View gzipped files with 'most'
NOARGS=65
NOTFOUND=66
NOTGZIP=67
if [ $# -eq 0 ] # same effect as: if [ -z "$1" ]
# $1 can exist, but be empty: zmost "" arg2 arg3
then
echo "Usage: `basename $0` filename" >&2
# Error message to stderr.
exit $NOARGS
# Returns 65 as exit status of script (error code).
fi
filename=$1
if [ ! -f "$filename" ] # Quoting $filename allows for possible spaces.
then
echo "File $filename not found!" >&2
# Error message to stderr.
exit $NOTFOUND
fi
if [ ${filename##*.} != "gz" ]
# Using bracket in variable substitution.
then
echo "File $1 is not a gzipped file!"
exit $NOTGZIP
fi
zcat $1 | most
# Uses the file viewer 'most' (similar to 'less').
# Later versions of 'most' have file decompression capabilities.
# May substitute 'more' or 'less', if desired.
exit $? # Script returns exit status of pipe.
# Actually "exit $?" unnecessary, as the script will, in any case,
# return the exit status of the last command executed.
|
Copyright © 1996-2008 by Dr. Nikolai Bezroukov. www.softpanorama.org was created as a service to the UN Sustainable Development Networking Programme (SDNP) in the author free time. Submit comments This document is an industrial compilation designed and created exclusively for educational use and is placed under the copyright of the Open Content License(OPL). Original materials copyright belong to respective owners. Quotes are made for educational purposes only in compliance with the fair use doctrine.
Standard disclaimer: The statements, views and opinions presented on this web page are those of the author and are not endorsed by, nor do they necessarily reflect, the opinions of the author present and former employers, SDNP or any other organization the author may be associated with. We do not warrant the correctness of the information provided or its fitness for any purpose.
Last modified: April 02, 2008