踏雪寻梅 发表于 2018-8-29 09:01:23

shell脚本基础知识(下)

  七、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///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///g'`
  
if [! -z $n1]
  
then   echo "请输入数字!"
  
       exit 1
  
fi
  
sum=0
  
for i in `seq1 $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
# 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 up9: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.00s0.25s0.00s sh select1.sh
  
root   pts/1    192.168.1.104    01:24   14:18   0.36s0.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更 老一些
  



页: [1]
查看完整版本: shell脚本基础知识(下)