************************** **************************
*** CASE语句 ***
**************************
**************************
case语句为多选语句。可以用case语句匹配一个值与一个模式。如果匹配成功,执行相匹配命令
======================================
case语句格式:
======================================
case 值 in
模式1)
命令1
;;
模式2)
命令2
;;
esac
======================================
case工作方式如上。取值后面必须为单词in,每一模式必须以右括号结束。取值可以为变量或常数
匹配发现取值符合某一模式后,其间所有命令开始执行直到遇到符号;;结束
取值将检测匹配的每一个模式。一旦模式匹配,则执行完匹配模式相应命令后不再继续其他模式。
如果无一匹配模式。使用星号*捕获该值,再接受其它输入。
模式部分可能包括元字符,与在命令行文件扩展名例子中使用过的匹配模式类型相同,即:
=========================
*任意字符
?任意单字符
[..]类或范围中任意字符
==========================
看一个小脚本先
====================================================
#!/bin/bash
#ScriptName caseselect
#Author:Honway
#DATE:2011-08-10
echo -n "Enter a number from 1-5 :"
read ANS
case $ANS in
1) echo "You select 1"
;;
2) echo "You select 2"
;;
3) echo "You select 3"
;;
4) echo "You select 4"
;;
5) echo "You select 5"
;;
*) echo "$0 : This is not between 1 and 5."
exit 1
;;
esac
====================================================
====================================================
很简单,不解释。
再来一脚本例子
====================================================
#!/bin/bash
#ScriptName caseterm
echo "Choices are .. vt100,vt102,vt220."
echo -n "Enter your terminal type: "
read TERMINAL
case $TERMINAL in
vt100|vt102) TERM=vt100
;;
vt220) TERM=vt220
;;
*) echo "$0 : Unknow response"
echo "Seting it to vt100 anyway,so there."
TERM=vt100
;;
esac
export TERM
echo "Your terminal is set to $TERM"
====================================================
这个也没什么特别,就是说明了可以用|来代替或命令.
==
再来一脚本
====================================================
#!/bin/bash
#caseans
echo -n "Do you wish to proceed [y..n] :"
read ANS
case $ANS in
y|Y|yes|Yes) echo "Yes is selected "
;;
n|N|no|No) echo "No is selected. "
exit 0 #No error so only use exit 0 to terminate
;;
*) echo "$0 : Unknow response" >&2
exit 1
;;
esac
====================================================
跟上面的脚本一样,只是说明|可以代替或命令
捕获输入并执行空命令
不一定要在匹配模式后加入命令,如果你原本不想做什么,只是在进一步处理前过滤出意外
如果要运行对应于一个会计部门的帐目报表,必须首先决定运行报表的类型前确认用户输入一个
有效的部门号,匹配所有可能值,其它值 无效。用case可以很容易实现
下面的脚本中如果用户输入部门号不是234,453,655或454,用户退出并返回可用信息。一旦
响应了用户的有效部门号,脚本就用同样的技术取得报表类型。
脚本如下
=============================================================
#!/bin/bash
#ScriptName
TYPE=""
echo -n "Enter the account dept NO. :"
read ACC
case $ACC in
234);;
453);;
655);;
454);;
*) echo "$0 : Unkonw dept NO:" >&2
echo "Try.. 234,453,655,454"
exit 1
;;
esac
echo " 1. post"
echo " 2. prior"
echo -n "Enter the type of report: "
read ACC_TYPE
case $ACC_TYPE in
1) TYPE=post;;
2)TYPE=prior;;
*) echo "$0 : Unkonw account type. " >&2
exit 1
;;
esac
echo "Now running report for dept $ACC for the type $TYPE"
=============================================================
=============================================================
缺省变量值
如果在读变量时输入回车键,不一定总是退出脚本,可以先测试是否已设置了变量,如果未设置,可以
设置该值。
下面脚本中,要求用户输入运行报表日期。如果用户输入回车键,则使用缺省日期星期六,并设置为WHEN
的取值。如果用户输入另外一天,这一天对于CASE语句是运行的有交日期,即星期六,星期四,星期一
脚本如下
=====================================================
#!/bin/bash
#ScriptName caserep
echo "--===============================--"
echo " Weekly Report "
echo "--===============================--"
echo -n "What day do you want to run report [Saturday]: "
read WHEN
echo "Validating..${WHEN:="Saturday"}"
case $WHEN in
Monday|MONDAY|mon)
;;
Sunday|SUNDAY|sun)
;;
Saturday|SATURDAY|SAT)
;;
*) echo "Are you nuts! this report can only be run on " >&2
echo " on a Saturday,Sunday or Monday " >&2
exit 1
;;
esac
echo "Report to run on $WHEN"
=====================================================
*************************
****** FOR循环 ******
*************************
for循环一般格式为:
---============================---
for 变量名 in 列表
do
命令1
命令2...
done
---============================---
当变量值在列表里,for循环即执行一次所有命令,使用变量名访问列表中取值,命令可为
任何有交的shell命令和语句。变量名为任何单词。in列表用法是可选的,如果不用它,for循环使用
命令行的位置参数
in列表可以包含替换,字符串和文件名。
一个简单的for循环
---============================---
#!/bin/bash
#ScriptName for_i
for loop in 1 2 3 4 5
do
echo $loop
done
---============================---
上面的脚本,变量loop在列表1 2 3 4 5中,等于是把1 2 3 4 5五个值赋给了loop.然后依次打印
[root@localhost Shell]# sh for_i.sh
1
2
3
4
5
打印字符串列表
下面for循环中,列表包含字符串"Orange Red Blue Grey",命令为echo,变量名为loop,echo命令使用
$loop反馈出列表中所有取值,直到列表为空
[root@localhost Shell]# cat forlist.sh
#!/bin/bash
#ScriptName forlist
for loop in Orange Red Blue Grey
do
echo $loop
done
[root@localhost Shell]# sh forlist.sh
Orange
Red
Blue
Grey
看下跟下面的有什么区别
[root@localhost Shell]# cat forlist.sh
#!/bin/bash
#ScriptName forlist
for loop in "Orange Red Blue Grey"
do
echo $loop
done
[root@localhost Shell]# sh forlist.sh
Orange Red Blue Grey
脚本中多了个双引号"",用双引号引起来,值相当于是一个,然后会被echo一下输出。
对for循环使用ls命令
这个循环执行ls命令,打印当前目录下所有文件
[root@localhost Shell]# cat forls.sh
#!/bin/bash
#ScriptName forls
for loop in `ls`
do
echo $loop
done
[root@localhost Shell]# sh forls.sh
LinuxShell
caseans.sh
caseparam.sh
caserep.sh
caseselect.sh
caseterm.sh
********************
对for循环使用参数
********************
在for循环中省去in列表选项时,它将接受命令行位置参数作为参数。实际上即指明:
forparamsin "$@"
或
forparamsin "$*"
""号可以省略,其实最好省略(个人实践中发现。)
下面的例子不使用in列表选项,for循环查看特定参数$@或$*,以从命令行中取得参数。
---==================================---
#!/bin/bash
#forparam2
for params
do
echo "You supplied $params as a command line option"
done
---==================================---
[root@localhost Shell]# sh forparam2.sh John Smith Tom Gim Kite
You supplied John as a command line option
You supplied Smith as a command line option
You supplied Tom as a command line option
You supplied Gim as a command line option
You supplied Kite as a command line option
每一个参数,都被打印出来了。
---================================================---
[root@localhost Shell]# cat forparam3.sh
#!/bin/bash
#ScriptName forparam3
for params in "$@"
do
echo "You supplied $params as a command line option"
done
---================================================---
[root@localhost Shell]# sh forparam3.sh John Tom Cat Dog God
You supplied John as a command line option
You supplied Tom as a command line option
You supplied Cat as a command line option
You supplied Dog as a command line option
You supplied God as a command line option
---================================================---
[root@localhost Shell]# cat forparam4.sh
#!/bin/bash
#ScriptName forparam4
for params in "$*"
do
echo "You supplied $params as a commad line option"
done
---================================================---
[root@localhost Shell]# sh forparam4.sh God Girl John
You supplied God Girl John as a commad line option
在使用$*的时候,如果想让结果输出多行。那么应该把""去掉,如下
---================================================---
#!/bin/bash
#ScriptName forparam4
for params in $*
do
echo "You supplied $params as a commad line option"
done
---================================================---
[root@localhost Shell]# sh forparam4.sh Dog God
You supplied Dog as a commad line option
You supplied God as a commad line option
---================================================---
由上,推出一个查找文件的小脚本。内容如下:
---================================================---
#!/bin/bash
#ScriptName forfind
for loop in $* //同上,in $* 或者$@ 或者省略in表示传递参数
do
find / -name $loop -print // -print可省略
done
---================================================---
使用for循环连接服务器
---================================================---
#!/bin/bash
#ScriptName forping
HOSTS=192.168.2.1
for loop in $HOSTS
do
ping -c 2 $loop
done
---================================================---
很简单,不解释。
---================================================---
#!/bin/bash
#ScriptName forssh
#AUTHOR: Honway
#DATE:2011-08-11
echo -n "Please enter your server's IP [default ip:localhost] :"
read IP
echo -n "Please enter your server's port[defaul port:22] : "
read PORT
echo -n "Please enter your username[default user:root] :"
read USERNAME
echo "Start connecting $IP........ "
echo "Please waiting...."
ssh ${USERNAME:=root}@${IP:=localhost} -p ${PORT:=22}
---================================================---
多文件转换
---================================================---
#!/bin/bash
#ScriptName forUC
for files in `ls *.sh`
do
cat $files | tr "[a-z]" "[A-Z]" >$files.UC
done
---================================================---
在当前目录查找所有.sh文件,然后把文件里的字母转换为大写字母,最后把转换后的结果写入到
当前文件名后面加.UC的文件中
删除所有指定文件类型中的空行
---================================================---
#!/bin/bash
#Forsed
for files in `ls *.sh`
do
sed -e "/^$/d" $files >$files.HOLD
mv $files.HOLD $files
done
---================================================---
删除所有.sh文件中的空行,这里有一个mv命令,如果在系统中直接运行mv,并且同名文件存在,会有
提示信息,但是脚本里面确没有。我们输入alias看到,mv ='m -i' ,所以我们运行时才有提示信息
如果把别名去掉,就没有了。那现在问题就很明显了,脚本里执行的时候,没有调用父Shell里的别名
循环计数
我们用for来计算当前目录的所有文件数
---================================================---
#!/bin/bash
#forcount
counter=0
for files in *
do
counter=`expr $counter + 1`
done
echo "There are $counter files in `pwd` we do need to process"
---================================================---
+1是为了统计的时候,加上这个脚本本身。
利用for循环,给所有当前在线的用户发送一封邮件
---================================================---
#!/bin/bash
#ScriptName formailit
WHO_ON=`who -u | awk '{print $1}'`
for user in $WHO_ON
do
mail $user