一、case语句

前面一直在用if语句实现选择分支,if语句固然可以完成多分支的条件判断,但代码不够清晰简洁,所以本章引入选择分支的另一种形式:case语句。该语句和if并无太大差别,主要作用是使代码的逻辑结构更清晰。case语句的用法格式为:

 

case 变量引用(${}) in

value1)

语句1

语句2

...

;;

value2)

语句1

语句2

...

;;

value3)

语句1

语句2

...

;;

*)

语句1

语句2

...

;;

esac

 

下面来举例演示case的用法:

 

1:写一个脚本,能接受参数gzipbzip2xz,而后能将/etc/目录归档备份至/backup目录,并以参数指定的形式压缩存放;文件名称包含脚本执行时刻的时间

[root@localhost tutor]# vim compress_case.sh

 

#!/bin/bash# Com=$1 if [ -z $Com]; then        Com=gzipfi [ -d /backup ]|| mkdir /backup case $Com ingzip)        tar zcf /backup/etc-`date+%F-%H-%M-%S`.tar.gz /etc/*        RetVal=$?        ;;bzip2)        tar jcf /backup/etc-`date+%F-%H-%M-%S`.tar.bz2 /etc/*        RetVal=$?        ;;xz)        tar Jcf /backup/etc-`date+%F-%H-%M-%S`.tar.xz /etc/*        RetVal=$?        ;;*)# 这里的 * 不是正则表达式,case中不支持正则表达式;但是case可以使用 |,表示或者        echo "Usage: `basename $0`{[gzip|bzip2|xz]}"        exit 6        ;;esac         [ $RetVal -eq 0 ] && echo"Backup etc finished.($Com)."

 

[root@localhost tutor]# ./compress_case.sh

tar: Removingleading `/' from member namesBackup etcfinished.(gzip).

[root@localhost tutor]# ls /backup

etc-2014-07-13-16-55-51.tar.gz

[root@localhost tutor]# ./compress_case.sh a

Usage:compress_case.sh {[gzip|bzip2|xz]}

[root@localhost tutor]# ./compress_case.sh xz

tar: Removingleading `/' from member namesBackup etcfinished.(xz).

[root@localhost tutor]# ls -hl /backup

total 15M-rw-r--r--. 1root root 9.5M Jul 13 16:55 etc-2014-07-13-16-55-51.tar.gz-rw-r--r--. 1root root 5.6M Jul 13 16:57 etc-2014-07-13-16-56-52.tar.xz

2. 前文中曾用if语句写过一个SysV风格的服务脚本(26_Shell语言————if条件判断之文件测试、短路操作符),该可以接受一个参数,其使用形式如下:

          script.sh {start|stop|restart|status}

如果参数为start,创建空文件/var/lock/subsys/script,并显示“Starting scriptsuccessfully.”;

如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;

如果参数为restart,则删除文件/var/lock/subsys/script后重新创建,并显示“Restarting scriptsuccessfully.”;

如果参数为status,那么:

          如果/var/lock/subsys/script文件存在,则显示为“script is running.

          否则,则显示为“script is stopped.

其它任何参数:则显示“script.sh {start|stop|restart|status}

现在将if语句改成case语句:

 

[root@localhost tutor]# vim service_case.sh

#!/bin/bash# SvcName=`basename$0`LockFile=/var/lock/subsys/$SvcName if [ $# -lt 1]; then        echo "Usage: `basename $0`{start|restart|stop|status}"        exit 5fi case $1 instart)        touch $LockFile        echo "Starting $SvcNamefinished."        ;;stop)        rm -f $LockFile        echo "Stopping $SvcNamefinished."        ;;restart)        rm -f $LockFile        touch $LockFile        echo "Restarting $SvcNamefinished."        ;;status)        if [ -e $LockFile ]; then                echo "$SvcName isrunning..."        else                echo "$SvcName isstoping..."        fi        ;;*)        echo "Usage: $SvcName {start|restart|stop|status}"        exit 6esac

 

[root@localhost tutor]# ./service_case.sh stat

Usage:service_case.sh {start|restart|stop|status}

[root@localhost tutor]# ./service_case.sh start

Startingservice_case.sh finished.

[root@localhost tutor]# ./service_case.sh restart

Restartingservice_case.sh finished.

[root@localhost tutor]# ./service_case.sh stop

Stoppingservice_case.sh finished.

[root@localhost tutor]# ./service_case.sh status

service_case.shis stoping...

 

二、bash如何与用户进行交互

bash语言中有个内置命令read,可以将用户通过键盘输入的内容保存到一个变量中。

[root@localhost tutor]# help read

read: read[-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-ttimeout] [-u fd] [name ...]

    Read a line from the standard input andsplit it into fields.

-p prompt output the string PROMPT without atrailing newline before attempting to read

# 指定提示信息

-t timeout time out and return failure if acomplete line of input is not read withint TIMEOUT seconds.

# 指定超时时间

 

[root@localhost tutor]# read Name

Mickey# 将用户输入的Mickey保存到变量Name中

[root@localhost tutor]# echo $Name

Mickey

 

[root@localhost tutor]# read Name

Darius# 重新输入一个值,将为该变量重新赋值

[root@localhost tutor]# echo $Name

Darius

 

[root@localhost tutor]# read A B

13 15# read还可以同时为多个变量赋值

 

[root@localhost tutor]# echo $A

13

[root@localhost tutor]# echo $B

15

[root@localhost tutor]# read A B

13 15 17# 变量和输入的值的个数不一致

[root@localhost tutor]# echo $A

13

[root@localhost tutor]# echo $B

15 17# 除了第一个值赋给了A,其余的都赋值给了B

[root@localhost tutor]# read A B

13# 用户输入的值的个数小于变量的个数

[root@localhost tutor]# echo $A

13# 只有变量A中有值,变量B为空串

 

1. 写一个脚本,来提示用户输入参数

 

[root@localhost tutor]# vim read.sh 

#!/bin/bash echo -n"Please Select a Compress Method [gzip|bzip2|xz]:"# -n选项表示显示了echo的内容后不换行read Comecho $Com

[root@localhost tutor]# bash read.sh

Please Selecta Compress Method [gzip|bzip2|xz]:gzipgzip

 

上述脚本中使用了echo的方法来提示用户输入参数,事实上read加上选项-p,本身就可以给用户以提示信息,故修改上述脚本:

 

[root@localhost tutor]# vim read.sh

#!/bin/bash read -p"Please Select a Compress Method [gzip|bzip2|xz]:"  Com# -p后面引号中的内容都会直接打印到屏幕上echo $Com

 

[root@localhost tutor]# bash read.sh

Please Selecta Compress Method [gzip|bzip2|xz]:bzip2bzip2

 

如果使用-t选项,还可以设定输入的超时时间:

[root@localhost tutor]# vim read.sh

#!/bin/bash read -t 5 -p"Please Select a Compress Method [gzip|bzip2|xz]:"  Com# 使用-t选项,设定超时时间为5秒echo $Com

[root@localhost tutor]# bash read.sh

PleaseSelect a Compress Method [gzip|bzip2|xz]:     # 用户一直没有输入,超时后显示为空

[root@localhost tutor]#

 

可以采用if判断语句,来为空值的情况设定默认值:

[root@localhost tutor]# vim read.sh

#!/bin/bash read -t 5 -p"Please Select a Compress Method [gzip|bzip2|xz]:"  Com[ -z $Com ]&& Com=gzip# 如果用户没有输入值,则默认值选择gzipecho $Com

 

[root@localhost tutor]# bash read.sh

Please Selecta Compress Method [gzip|bzip2|xz]:gzip# 这里gzip没有换行,因为-p选项默认是不换行的

 

2. 写一个脚本,判断用户输入的是哪种字符 

 

[root@localhost tutor]# vim user_input.sh

#!/bin/bash#read -p"Input a Character: " Char case $Char in[0-9])        echo "A digit."        ;;[[:lower:]])        echo "A lower."        ;;[[:upper:]])        echo "An upper."        ;;[[:punct:]])        echo "A punction."        ;;*)        echo "Special Character."esac

 

[root@localhost tutor]# chmod +x user_input.sh

[root@localhost tutor]# ./user_input.sh

Input aCharacter: 2A digit.

[root@localhost tutor]# ./user_input.sh

Input aCharacter: aA lower.

[root@localhost tutor]# ./user_input.sh

Input aCharacter: AA lower.

[root@localhost tutor]# ./user_input.sh

Input aCharacter: ,A punction.

[root@localhost tutor]# ./user_input.sh

Input aCharacter: ^[SpecialCharacter.

 

3. 写一个脚本,提示用户是否接受协议

 

[root@localhost tutor]# vim agree.sh

#!/bin/bash# read -p"Do you agree: [Yes|No]:" YesNo case $YesNo in y|Y|[yY][eE][sS])        echo "Agreed, proceed...";;n|N|[nN][oO])        echo "Disagreed,intterupt.";;*)        echo "Invalid input."esac

[root@localhost tutor]# ./agree.sh

Do you agree:[Yes|No]:yesAgreed,proceed...

[root@localhost tutor]# ./agree.sh

Do you agree:[Yes|No]:nDisagreed,intterupt.

[root@localhost tutor]# ./agree.sh

Do you agree:[Yes|No]:aInvalid input.

 

4. 显示如下菜单,

1、显示如下菜单给用户:

m|M) showmemory usages;

d|D) showdisk usages;

q|Q) quit

2、如果用户选择了第一项,则显示内存使用信息;如果选择了第二项,则显示磁盘挂载及使用相关信息;

   如果是第三项,退出,并显示选择退出;其它任何内容,均说明错误选项;

 

[root@localhost tutor]# vim show_menu.sh

 

cat <

 

 

[root@localhost tutor]# chmod +x show_menu.sh

[root@localhost tutor]# ./show_menu.sh 

m|M showmemory usages;d|D show diskusages;q|Q quit Your choice: m             total       used       free    shared    buffers     cachedMem:           996        828        167          0        100        411-/+ buffers/cache:        316        679Swap:         2215          0       2215

[root@localhost tutor]# ./show_menu.sh

m|M showmemory usages;d|D show diskusages;q|Q quit Your choice: DFilesystem                    Size  Used Avail Use% Mounted on/dev/mapper/VolGroup-lv_root   23G 4.5G   17G  22% /tmpfs                         499M  120K 499M   1% /dev/shm/dev/sda1                     485M   35M 426M   8% /boot/dev/sdb3                     9.9G   36M 9.7G   1% /mydata/dev/sr0                      288K 288K     0 100%/media/20140715_2041

[root@localhost tutor]# ./show_menu.sh

m|M showmemory usages;d|D show diskusages;q|Q quit Your choice: QQuit...

[root@localhost tutor]# ./show_menu.sh

m|M showmemory usages;d|D show diskusages;q|Q quit Your choice: aInvalid input.