条件选择
case
用 case 语句代替多层 if-then-else-fi 语句是不错的选择。它使您可以将多个值与一个变量匹配。它更容易读写。
case $variable-name in
pattern1)
command1
...
....
commandN
;;
pattern2)
command1
...
....
commandN
;;
patternN)
command1
...
....
commandN
;;
*)
esac
# 或者
case $variable-name in
pattern1|pattern2|pattern3)
command1
...
....
commandN
;;
pattern4|pattern5|pattern6)
command1
...
....
commandN
;;
pattern7|pattern8|patternN)
command1
...
....
commandN
;;
*)
esac
使用 case 语句,您可以轻松检查模式(条件),然后在条件评估为 true 时处理命令行。换句话说,将 $variable-name
与模式进行比较,直到找到匹配项为止。*)
是默认值,如果没有找到匹配项则执行。该模式可以包含通配符。您必须包括 ;;
在每个命令的末尾 N。Shell 会执行所有语句,直到两个相邻的分号为止。总是需要 esac 来指示案例陈述的结尾。
#!/bin/bash
# if no command line arg given
# set rental to Unknown
if [ -z $1 ]
then
rental="*** Unknown vehicle ***"
elif [ -n $1 ]
then
# otherwise make first arg as a rental
rental=$1
fi
# use case statement to make decision for rental
case $rental in
"car") echo "For $rental rental is Rs.20 per k/m.";;
"van") echo "For $rental rental is Rs.10 per k/m.";;
"jeep") echo "For $rental rental is Rs.5 per k/m.";;
"bicycle") echo "For $rental rental 20 paisa per k/m.";;
"enfield") echo "For $rental rental Rs.3 per k/m.";;
"thunderbird") echo "For $rental rental Rs.5 per k/m.";;
*) echo "Sorry, I can not get a $rental rental for you!";;
esac
case 语句首先针对每个选项检查 $rental 是否匹配。如果匹配 “car”,则 echo 命令将显示 car 的租金。如果与 “van” 匹配,则 echo 命令将显示 van 的租期,依此类推。如果不匹配,即 *
(默认选项),则会打印相应的警告消息。多重匹配的示例如下:
#!/bin/bash
NOW=$(date +"%a")
case $NOW in
Mon)
echo "Full backup";;
Tue|Wed|Thu|Fri)
echo "Partial backup";;
Sat|Sun)
echo "No backup";;
*) ;;
esac
以下 shell 脚本演示了使用 case 语句(casecmdargs.sh)处理命令行参数的概念:
#!/bin/bash
OPT=$1 # option
FILE=$2 # filename
# test -e and -E command line args matching
case $OPT in
-e|-E)
echo "Editing $2 file..."
# make sure filename is passed else an error displayed
[ -z $FILE ] && { echo "File name missing"; exit 1; } || vi $FILE
;;
-c|-C)
echo "Displaying $2 file..."
[ -z $FILE ] && { echo "File name missing"; exit 1; } || cat $FILE
;;
-d|-D)
echo "Today is $(date)"
;;
*)
echo "Bad argument!"
echo "Usage: $0 -ecd filename"
echo " -e file : Edit file."
echo " -c file : Display file."
echo " -d : Display current date and time."
;;
esac
最后的示例中,我们可以将多种备份选择整合到某个单一脚本中:
#!/bin/bash
# A shell script to backup mysql, webserver and files to tape
opt=$1
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Backup shell script utility"
echo "Usage: $0 {sql|sync|tar}"
echo " sql : Run mySQL backup utility."
echo " sync : Run web server backup utility."
echo " tar : Run tape backup utility." ;;
esac
chmod +x allinonebackup.sh
# run sql backup
./allinonebackup.sh sql
# Dump file system using tape device
./allinonebackup.sh tar
# however, the following will fail as patterns are case sensitive
# you must use command line argument tar and not TAR, Tar, TaR etc.
./allinonebackup.sh TAR
大小写敏感
根据大写和小写字母的不同用法,单词的含义可能会有所不同。Linux 允许文件具有多个名称。例如,Sample.txt,SAMPLE.txt 和 SAMPLE.TXT 都是三个不同的文件名。区分大小写的问题也适用于 case 语句。例如,我们的备份脚本可以执行如下:
./allinonebackup.sh tar
但是,以下示例将不起作用,因为模式区分大小写。您必须使用命令行参数 tar 而不是 TAR,Tar,TaR 等:
./allinonebackup.sh TAR
转化为小写
您可以使用 tr 命令将模式转换为小写形式,此处的字符串如下:
echo "TeSt" | tr '[:upper:]' '[:lower:]'
var="TesT"
tr '[:upper:]' '[:lower:]' <<<"$var"
您可以按以下方式更新脚本:
#!/bin/bash
# A shell script to backup mysql, webserver and files to tape
# allinonebackup.sh version 2.0
# -------------------------------------------------------
# covert all passed arguments to lowercase using
# tr command and here strings
opt=$( tr '[:upper:]' '[:lower:]' <<<"$1" )
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Backup shell script utility"
echo "Usage: $0 {sql|sync|tar}"
echo " sql : Run mySQL backup utility."
echo " sync : Run web server backup utility."
echo " tar : Run tape backup utility." ;;
esac
使用正则表达式
大小写命令模式支持正则表达式,这些正则表达式提供了一种简洁而灵活的方式来标识单词或字符模式。例如,您可以使用以下语法匹配 tar 模式:
[Tt][Aa][Rr]
上面称为方括号表达式。它与括号中包含的单个字符匹配。
# A shell script to backup mysql, webserver and files to tape
opt=$1
#########################################################
# Use regex to match all command line arguments #
# [Tt][Aa][Rr] matches "tar", "TAR", "taR", "TaR", etc #
# [Ss][Qq][Ll] matches "sql", "SQL", "SQl", "SqL", etc #
#########################################################
case $opt in
[Ss][Qq][Ll])
echo "Running mysql backup using mysqldump tool..."
;;
[Ss][Yy][Nn][Cc])
echo "Running backup using rsync tool..."
;;
[Tt][Aa][Rr])
echo "Running tape backup using tar tool..."
;;
*)
echo "Backup shell script utility"
echo "Usage: $0 {sql|sync|tar}"
echo " sql : Run mySQL backup utility."
echo " sync : Run web server backup utility."
echo " tar : Run tape backup utilty." ;;
esac
启用大小写不敏感
# 启用
shopt -s nocasematch
# 关闭
shopt -u nocasematch
这是相同的更新版本:
# A shell script to backup mysql, webserver and files to tape
opt=$1
# Turn on a case-insensitive matching (-s set nocasematch)
shopt -s nocasematch
case $opt in
sql)
echo "Running mysql backup using mysqldump tool..."
;;
sync)
echo "Running backup using rsync tool..."
;;
tar)
echo "Running tape backup using tar tool..."
;;
*)
echo "Backup shell script utility"
echo "Usage: $0 {sql|sync|tar}"
echo " sql : Run mySQL backup utility."
echo " sync : Run web server backup utility."
echo " tar : Run tape backup utilty." ;;
esac
# Turn off a case-insensitive matching (-u unset nocasematch)
shopt -u nocasematch