七、shell中的case判断
格式: case 变量名 in
value1)
command
;;
value2)
command
;;
*)
commond
;;
esac
在case程序中,可以在条件中使用|,表示或的意思, 比如:
2|3)
command
;;
当变量为2或者3时,执行该部分命令。
应用举例:
[ root@hpf-linux shell]# cat test7.sh #!/bin/bash read -p "请输入学生的成绩: " num n1=`echo $num | sed 's/[0-9]//g'` //判断是否为数字 if [ ! -z $n1 ] then echo "这不是一个数字请从新输入!!" exit 1 fi if [[ $num -gt 100 || $num -lt 0 ]] then echo "学生的成绩为0-100,请从新输入!" exit 1 elif [ $num -ge 90 ] && [ $num -le 100 ] then tag=1 elif [ $num -ge 80 ] && [ $num -le 90 ] then tag=2 elif [ $num -ge 70 ] && [ $num -le 80 ] then tag=3 elif [ $num -ge 60 ] && [ $num -le 70 ] then tag=4 else tag=5 fi case $tag in 1) echo "优秀!" ;; 2) echo "良好!" ;; 3) echo "中等!" ;; 4) echo "万岁!及格啦!" ;; 5) echo "抱歉!你不及格!还需要补考!" ;; esac [ root@hpf-linux shell]# sh test7.sh 请输入学生的成绩: 111 学生的成绩为0-100,请从新输入! [ root@hpf-linux shell]# sh test7.sh 请输入学生的成绩: dagfag 这不是一个数字请从新输入!! [ root@hpf-linux shell]# sh test7.sh 请输入学生的成绩: 89 良好!
通过上例可以看到case判断的使用,虽然例子不是很好,但是比较全面的练习了if和case语句,在编写时由于自己的马虎在判断句if [ ! -z $n1 ]中-z少写了- 导致出现了错误,请大家引以为戒!
八、shell脚本中的循环
1、for循环
语法结构: for 变量名 in 条件; do … done ;
应用举例:
[ root@hpf-linux shell]# cat test8.sh #!/bin/bash read -p "请输入一个数字:" n n1=`echo $n | sed 's/[0-9]//g'` if [ ! -z $n1 ] then echo "请输入数字!" exit 1 fi sum=0 for i in `seq 1 $n` do sum=$(($i+$sum)) done echo $sum
[ root@hpf-linux shell]# sh test8.sh -x 请输入一个数字:10 55 [ root@hpf-linux shell]# sh test8.sh -x 请输入一个数字:999 499500 [ root@hpf-linux shell]# sh test8.sh -x 请输入一个数字:99999 4999950000 [ root@hpf-linux shell]# sh test8.sh -x 请输入一个数字:5645757 15937288874403
上例为手动输入一个数计算其从0加到本身所得的总和并输出,在加最后一个数时CPU运算了二十多秒,所以没事还是不要这样玩。
2、while 循环
语法结构: while 条件; do … done 死循环用 : 表示 ;
break直接结束本层循环; continue忽略continue之下的代码,直接进行下一次循环 ;
exit 直接退出shell ;
应用举例:
[ root@hpf-linux shell]# cat test9.sh #/bin/bash while : do load=`w|awk -F 'load average: ' '{print$2}'|cut -d. -f1` processor=`cat /proc/cpuinfo | grep 'processor' | wc -l` if [ $load -lt $processor ] //注意为了能收到邮件我写成小于,在长使用是用大于的 then top -bn1|mail -s " load is high: $load" XXXX @126.com else exit 0 fi sleep 30 done
上例是一个简单的判断服务器是否过载,若过载则将信息发送给126邮箱,并且是30秒一封,这个例子是简单的通过脚本监控系统的负载,若要更好的监控还是建议使用专业的监控软件cacti/nagios/zabbix等工具。
[ root@hpf-linux shell]# cat test9.sh #/bin/bash while : do load=`w|awk -F 'load average: ' '{print$2}'|cut -d. -f1` processor=`cat /proc/cpuinfo | grep 'processor' | wc -l` if [ $load -lt $processor ] //注意为了能收到邮件我写成小于,在长使用是用大于的 then top -bn1|mail -s " load is high: $load" XXXX @126.com else exit 0 fi sleep 30 done
上例是简单的介绍使用在while语句中用同continue和break跳出循环的区别,简单的讲:
break :结束并退出循环 。
continue :在循环中不执行continue下面的代码,转而进入下一轮循环
exit :退出脚本, 常带一个整数给系统,如 exit 0
return :在函数中将数据返回,或返回一个结果给调用函数的脚本
九、shell函数
1、shell函数简介
shell一个非常重要的特性是它可作为一种编程语言来使用。因为shell是一个解释器,所以它不能对为它编写的程序进行编译,而是在每次从磁盘加载这些程序时对它们进行解释。而程序的加载和解释都是非常耗时的。针对此问题,许多shell(如BourneAgainShell)都包含shell函数,shell把这些函数放在内存中,这样每次需要执行它们时就不必再从磁盘读入。shell还以一种内部格式来存放这些函数,这样就不必耗费大量的时间来解释它们。
2、shell函数语法
函数由两部分组成:函数标题、函数体。
标题是函数名。函数体是函数内的命令集合。标题名应该唯一;如果不是,将会混淆结果,因为脚本在查看调用脚本前将首先搜索函数调用相应的s h e l l。
定义函数的格式为:
函数名()
{
命令1
. . .
}
或者
函数名(){
命令1
. . .
}
两者方式都可行。如果愿意,可在函数名前加上关键字f u n c t i o n,这取决于使用者。
f u n c t i o n 函数名()
{ ...
}
可以将函数看作是脚本中的一段代码,但是有一个主要区别。执行函数时,它保留当前s h e l l和内存信息。此外如果执行或调用一个脚本文件中的另一段代码,将创建一个单独的 s h e l l,因而去除所有原脚本中定义的存在变量。 函数可以放在同一个文件中作为一段代码,也可以放在只包含函数的单独文件中。函数不必包含很多语句或命令,甚至可以只包含一个e c h o语句,这取决于使用者。参数返回,可以显示加:return 返回,如果不加,将以最后一条命令运行结果,作为返回值。 return后跟数值n(0-255)
3、shell函数应用举例
查看ip地址的函数;输入一个网卡名,输出网卡对应的ip地址;
[ root@hpf-linux shell]# cat fun1.sh #/bin/bash read -p "请输入网卡:" network ip () { ifconfig $network|head -2|tail -1|awk -F ':' '{print$2}'|awk '{print$1}' } case $network in eth*) echo "这是Ethernet网卡," ipaddr=`ip $network` echo "$network的IP是:$ipaddr" ;; lo) echo "这是回环网卡" ipaddr=`ip $network` echo "$network的IP是:$ipaddr" ;; *) echo "你输入的不正确,请从新输入!" ;; esac
扩展学习:
select也是循环的一种,它比较适合用在用户选择的情况下。
比如,我们有一个这样的需求,运行脚本后,让用户去选择数字,选择1,会运行w命令,选择2运行top命令,选择3运行free命令,选择4退出。
#!/bin/bash PS3="Please select a number: " echo "Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit" echo select command in w top free quit do case $command in w) w ;; top) top ;; free) free ;; quit) exit ;; *) echo "Please input a number:(1-4)." esac done
[root@hpf-linuxshell]# sh select1.sh Please chose a number, 1: run w, 2: run top, 3: run free, 4: quit 1) w 2) top 3) free 4) quit Please select a number: 1 09:34:03 up 9:39, 2 users, load average: 0.00, 0.00, 0.00 USER TTY FROM LOGIN@ IDLE JCPU PCPU WHAT root pts/0 192.168.1.104 00:22 0.00s 0.25s 0.00s sh select1.sh root pts/1 192.168.1.104 01:24 14:18 0.36s 0.36s -bash Please select a number: 4
文件测试
单目测试:
-e file :测试文件是否存在
-a file :测试文件是否存在
-f file: 测试是否为普通文件
-d 目录: 测试是否为目录文件
-b somefile : 测试文件是否存在并且是否为一个块设备文件
-c somefile : 测试文件是否存在并且是否为一个字符设备文件
-h|-L somefile : 测试文件是否存在并且是否为符号链接文件
-p somefile : 测试文件是否存在并且是否为管道文件:
-S somefile : 测试文件是否存在并且是否为套接字文件:
-r somefile: 测试其有效用户是否对此文件有读取权限
-w somefile: 测试其有效用户是否对此文件有写权限
-x somefile: 测试其有效用户是否对此文件有执行权限
-s somefile: 测试文件是否存在并且不空
双目测试:
file1 -nt file2 :测试file1是否比file2更 新一些
file1 -ot file2 :测试file1是否比file2更 老一些