27_Shell语言————case语句、bash如何与用户进行交互(case、read)
一、case语句前面一直在用if语句实现选择分支,if语句固然可以完成多分支的条件判断,但代码不够清晰简洁,所以本章引入选择分支的另一种形式:case语句。该语句和if并无太大差别,主要作用是使代码的逻辑结构更清晰。case语句的用法格式为:
case 变量引用(${}) in
value1)
语句1
语句2
...
;;
value2)
语句1
语句2
...
;;
value3)
语句1
语句2
...
;;
*)
语句1
语句2
...
;;
esac
下面来举例演示case的用法:
例1:写一个脚本,能接受参数gzip、bzip2或xz,而后能将/etc/目录归档备份至/backup目录,并以参数指定的形式压缩存放;文件名称包含脚本执行时刻的时间。
# vim compress_case.sh
#!/bin/bash
#
Com=$1
if [ -z $Com]; then
Com=gzip
fi
[ -d /backup ]|| mkdir /backup
case $Com in
gzip)
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`{}"
exit 6
;;
esac
[ $RetVal -eq 0 ] && echo"Backup etc finished.($Com)."
# ./compress_case.sh
tar: Removingleading `/' from member names
Backup etcfinished.(gzip).
# ls /backup
etc-2014-07-13-16-55-51.tar.gz # ./compress_case.sh a
Usage:compress_case.sh {} # ./compress_case.sh xz
tar: Removingleading `/' from member names
Backup etcfinished.(xz).
# 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语句:
# 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 5
fi
case $1 in
start)
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 6
esac
# ./service_case.sh stat
Usage:service_case.sh {start|restart|stop|status} # ./service_case.sh start
Startingservice_case.sh finished. # ./service_case.sh restart
Restartingservice_case.sh finished. # ./service_case.sh stop
Stoppingservice_case.sh finished. # ./service_case.sh status
service_case.shis stoping... 二、bash如何与用户进行交互
bash语言中有个内置命令read,可以将用户通过键盘输入的内容保存到一个变量中。
# help read
read: read[-ers] [-a array] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-ttimeout] [-u fd]
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.
# 指定超时时间
# read Name
Mickey
# 将用户输入的Mickey保存到变量Name中
# echo $Name
Mickey # read Name
Darius
# 重新输入一个值,将为该变量重新赋值
# echo $Name
Darius # read A B
13 15
# read还可以同时为多个变量赋值
# echo $A
13 # echo $B
15 # read A B
13 15 17
# 变量和输入的值的个数不一致
# echo $A
13 # echo $B
15 17
# 除了第一个值赋给了A,其余的都赋值给了B
# read A B
13
# 用户输入的值的个数小于变量的个数
# echo $A
13
# 只有变量A中有值,变量B为空串
例1. 写一个脚本,来提示用户输入参数:
# vim read.sh
#!/bin/bash
echo -n"Please Select a Compress Method :"
# -n选项表示显示了echo的内容后不换行
read Com
echo $Com
# bash read.sh
Please Selecta Compress Method :gzip
gzip
上述脚本中使用了echo的方法来提示用户输入参数,事实上read加上选项-p,本身就可以给用户以提示信息,故修改上述脚本:
# vim read.sh
#!/bin/bash
read -p"Please Select a Compress Method :"Com
# -p后面引号中的内容都会直接打印到屏幕上
echo $Com
# bash read.sh
Please Selecta Compress Method :bzip2
bzip2
如果使用-t选项,还可以设定输入的超时时间:
# vim read.sh
#!/bin/bash
read -t 5 -p"Please Select a Compress Method :"Com
# 使用-t选项,设定超时时间为5秒
echo $Com
# bash read.sh
PleaseSelect a Compress Method :
# 用户一直没有输入,超时后显示为空
#
可以采用if判断语句,来为空值的情况设定默认值:
# vim read.sh
#!/bin/bash
read -t 5 -p"Please Select a Compress Method :"Com
[ -z $Com ]&& Com=gzip
# 如果用户没有输入值,则默认值选择gzip
echo $Com
# bash read.sh
Please Selecta Compress Method :gzip
# 这里gzip没有换行,因为-p选项默认是不换行的
例2. 写一个脚本,判断用户输入的是哪种字符:
# vim user_input.sh
#!/bin/bash
#
read -p"Input a Character: " Char
case $Char in
)
echo "A digit."
;;
[[:lower:]])
echo "A lower."
;;
[[:upper:]])
echo "An upper."
;;
[[:punct:]])
echo "A punction."
;;
*)
echo "Special Character."
esac
# chmod +x user_input.sh
# ./user_input.sh
Input aCharacter: 2
A digit.
# ./user_input.sh
Input aCharacter: a
A lower.
# ./user_input.sh
Input aCharacter: A
A lower.
# ./user_input.sh
Input aCharacter: ,
A punction.
# ./user_input.sh
Input aCharacter: ^[
SpecialCharacter.
例3. 写一个脚本,提示用户是否接受协议:
# vim agree.sh
#!/bin/bash
#
read -p"Do you agree: :" YesNo
case $YesNo in
y|Y|)
echo "Agreed, proceed...";;
n|N|)
echo "Disagreed,intterupt.";;
*)
echo "Invalid input."
esac
# ./agree.sh
Do you agree::yes
Agreed,proceed...
# ./agree.sh
Do you agree::n
Disagreed,intterupt.
# ./agree.sh
Do you agree::a
Invalid input.
例4. 显示如下菜单,
1、显示如下菜单给用户:
m|M) showmemory usages;
d|D) showdisk usages;
q|Q) quit
2、如果用户选择了第一项,则显示内存使用信息;如果选择了第二项,则显示磁盘挂载及使用相关信息;
如果是第三项,退出,并显示选择退出;其它任何内容,均说明错误选项;
# vim show_menu.sh
cat
页:
[1]