shuaiwei588 发表于 2018-8-21 09:29:54

shell脚本之判断 if,elif, case

  单分支if语句:
  if 条件; then
  语句1
  语句2
  ...
  fi
  if 条件
  then
  例子1:写一个脚本,实现如下功能:
  如果用户存在,就说明其存在;
  #!/bin/bash
  #
  UserName=user1
  if grep "^$UserName\>" /etc/passwd &> /dev/null; then
  echo "$UserName exists."
  fi
  #!/bin/bash
  UserName=user1

  if>  echo "$UserName exists."
  fi
  练习:写一个脚本,实现如下功能:
  如果用存在,就显示其UID和SHELL;
  #!/bin/bash
  #
  UserName=user1

  if>  grep "^$UserName\>" /etc/passwd | cut -d: -f3,7
  fi
  练习:写一个脚本,实现如下功能:
  如果设备/dev/sda3已经挂载,就显示其挂载点;
  #!/bin/bash
  #
  Device='/dev/sda3'
  if mount | grep "^$Device" &> /dev/null; then
  mount | grep "/dev/sda3" | cut -d' ' -f3
  fi
  练习:写一个脚本,实现如下功能:
  如果/etc/rc.d/rc.sysinit中有空白行,就显示其空白行数;
  #!/bin/bash
  #
  File='/etc/rc.d/rc.sysinit'
  if grep "^$" $File &> /dev/null; then
  grep "^$" $File | wc -l
  fi
  双分支if语句:
  if 条件; then
  语句1
  语句2
  ...
  else
  语句1
  语句2
  ...
  fi
  例子:写一个脚本:
  如果指定的用户存,先说明其已经存在,并显示其ID号和SHELL;否则,就添加用户,并显示其ID号;
  练习:写一个脚本,实现如下功能:
  如果设备/dev/sda3已经挂载,就显示其挂载点;否则,就说明其未挂载或设备不存在;
  #!/bin/bash
  #
  Device='/dev/sda3'
  if mount | grep "^$Device" &> /dev/null; then
  mount | grep "/dev/sda3" | cut -d' ' -f3
  else
  echo "$Device not mounted or not exist."
  fi
  bash条件测试:
  [ expression ]
  ` expression `
  test expression
  整数测试
  字符测试
  文件测试
  整数测试:
  expression: 数值1 比较符号 数值2
  $A 比较符号 $B
  大于:-gt, 例如 $A -gt $B
  大于或等于:-ge
  等于:-eq
  小于:-lt
  小于或等于:-le
  不等于:-ne
  例子:写一个脚本,生成两个随机数,比较其大小;显示大数;
  bash有个内置变量:$RANDOM
  #!/bin/bash
  #
  A=$RANDOM
  B=$RANDOM
  if [ $A -ge $B ]; then
  echo "Max number is $A."
  else
  echo "Max number is $B."
  fi
  练习:写一脚本,随机生成一个整数,判定,显示其奇偶性;
  #!/bin/bash
  #
  A=$RANDOM
  if [ $[$A%2] -eq 0 ]; then
  echo "$A: Even"
  else
  echo "$A: Odd"
  fi
  练习:给定一个用户,如果其ID号大于499,就说明其是普通用户,否则,就说明其是管理员或系统用户;
  #!/bin/bash
  #
  UserName=daemon
  Uid=`id -u $UserName`
  if [ $Uid -gt 499 ]; then
  echo "A common user: $UserName."
  else
  echo "admin user or system user: $UserName."
  fi
  练习:求200以内所有为3的整数倍的整数之和;
  #!/bin/bash
  #
  Sum=0
  for I in {1..200}; do
  if [ $[$I%3] -eq 0 ]; then
  Sum=$[$Sum+$I]
  fi
  done
  echo "Sum: $Sum."
  练习:给定一个用户,如果其UID等于GID,就说明这是个“good guy”,否则,“Bad guy.”
  #!/bin/bash
  #
  UserName=user1
  if [ `id -u $UserName` -eq `id -g $UserName` ]; then
  echo "Good Guy."
  else
  echo "Bad Guy."
  fi
  写一个脚本:
  计算100以内所有奇数的和以及所有偶数的和;分别显示之;
  #!/bin/bash
  #
  EvenSum=0
  OddSum=0
  for I in {1..100}; do
  if [ $[$I%2] -eq 0 ]; then
  EvenSum=$[$EvenSum+$I]
  else
  OddSum=$[$OddSum+$I]
  fi
  done
  echo "EvenSum is: $EvenSum. OddSum is: $OddSum."
  bash编程: 位置变量
  $1, $2, $3, $4, ...
  写一个脚本:
  计算N以内所有奇数的和以及所有偶数的和;分别显示之;N是通过参数传递过来的正整数;
  #!/bin/bash
  #
  EvenSum=0
  OddSum=0
  for I in `seq 1 $1`;do
  if [ $[$I%2] -eq 1 ]; then
  OddSum=$[$OddSum+$I]
  else
  EvenSum=$[$EvenSum+$I]
  fi
  done
  echo "EvenSum: $EvenSum."
  echo "OddSUm: $OddSum."
  echo "Sum: $[$EvenSum+$OddSum]"
  shift :实现位置参数轮替;
  例子:通过参数传递n个正整数给脚本,求其和;
  #!/bin/bash
  #
  Sum=0
  for I in `seq 1 $#`; do
  Sum=$[$Sum+$1]
  shift
  done
  echo $Sum
  练习,写一个脚本,完成以下要求:
  1、添加10个用户user1, user2, ..., user10;但要先判断用户是否存在,不存在而后再添加;
  2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
  3、最后显示当前系统上共有多少个用户;
  #!/bin/bash
  #
  Count=0
  for I in {1..10}; do

  if>  echo "user$I exists."
  else
  useradd user$I
  echo "Add user$I successfully."
  Count=$[$Count+1]
  fi
  done
  echo "Add $Count new users."
  echo "Total users: `wc -l /etc/passwd | cut -d' ' -f1`."
  练习,写一个脚本,完成以下要求:
  1、通过参数传递一系列用户名给脚本,让脚本添加这些用户;但要先判断用户是否存在,不存在而后再添加;
  2、添加完成后,显示一共添加了几个用户;当然,不能包括因为事先存在而没有添加的;
  #!/bin/bash
  #
  Count=0
  for UserName in $@; do

  if>  echo "$UserName exists."
  else
  useradd $UserName
  echo "Add $UserName successfully."
  Count=$[$Count+1]
  fi
  done
  echo "Add $Count new users."
  练习,写一个脚本,完成以下要求:
  给定一个用户:
  1、如果其UID为0,就显示此为管理员;
  2、否则,就显示其为普通用户;
  练习:写一个脚本,完成以下要求:
  通过参数传递一个磁盘设备文件给脚本,让脚本来判断其是否有扩展分区;有则显示有,否则显示为无;
  练习:写一个脚本
  给定一个文件,比如/etc/inittab
  判断这个文件中是否有空白行;
  如果有,则显示其空白行数;否则,显示没有空白行。
  练习:写一个脚本;(要求:不使用id命令获得其id号;)
  给定一个用户,判断其UID与GID是否一样
  如果一样,就显示此用户为“good guy”;否则,就显示此用户为“bad guy”。
  练习:写一个脚本
  给脚本传递两个参数(整数);
  显示此两者之和,之乘积;
  写一个脚本,分别显示当前系统上所有默认shell为bash的用户和默认shell为/sbin/nologin的用户,并统计各类shell下的用户总数。显示结果形如:
  BASH,3users,they are:
  root,redhat,gentoo
  NOLOGIN, 2users, they are:
  bin,ftp
  bash脚本知识点:
  条件测试方式:
  bash命令;
  [ expression ]
  ` expression `
  test expression
  条件测试:
  整数测试
  大于:-gt
  小于:-lt
  等于:-eq
  大等:-ge
  小等:-le
  不等:-ne
  字符测试
  文件测试
  命令执行状态返回值: 0-255
  0: 正确执行
  1-255: 错误执行
  exit
  脚本执行的最后一条件命令的状态返回值;
  bash字符测试:
  >: 大于
    如果其生产商为GenuineIntel,就显示其为Intel公司;
  否则,就显示其为AMD公司;
  #!/bin/bash
  #
  Vendor=`grep "vendor_id" /proc/cpuinfo | uniq | cut -d: -f2`
  if [[ "$Vendor" =~ [[:space:]]*GenuineIntel$ ]]; then
  echo "Intel"
  else
  echo "AMD"
  fi
  练习:写一个脚本
  通过参数传递一个字符串给脚本,如果传递的字符串为“memory”或“Memory”,就以MB为单位显示当前主机的内存信息;
  否则,就显示/proc/uptime文件的内容。
  #!/bin/bash
  #
  if [[ $1 =~ emory$ ]]; then
  free -m
  else
  cat /proc/uptime
  fi
  bash知识点:组合条件测试
  -a: 与
  -o: 或
  !: 非,单目操作符
  A=3
  UID>=1, UID  echo "No such user."
  exit 6
  fi
  if [ `id -u $1` -eq `id -g $1` ]; then
  echo "Good Guy"
  else
  echo "Bad Guy"
  fi
  练习:写一个脚本
  通过参数传递一个字符串给脚本,如果传递的字符串为“memory”或“Memory”,就以MB为单位显示当前主机的内存信息;
  否则,就显示/proc/uptime文件的内容。
  [ $1 == "memory" -o $1 == "Memory" ]
  bash条件判断之多分支if语句:
  语法格式:
  if 条件1; then
  语句1
  语句2
  ...
  elif 条件2; then
  语句1
  语句2
  ...
  elif 条件3; then
  语句1
  语句2
  ...
  else
  语句1
  语句2
  ...
  fi
  写一个脚本:

  判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor>  如果其生产商为GenuineIntel,就显示其为Intel公司;
  如果其生产商为AuthenticAMD,就显示其为AMD公司;
  否则,就显示无法识别;
  #!/bin/bash
  #
  Vendor=`grep "vendor_id" /proc/cpuinfo | uniq | cut -d: -f2`
  if [[ $Vendor =~ [[:space:]]*GenuineIntel$ ]]; then
  echo "intel"
  elif [[ $Vendor =~ [[:space:]]*AuthenticAMD$ ]]; then
  echo "AMD"
  else
  echo "Unknown"
  fi
  练习:通过参数传递给脚本一个字符串,如Fedora, Gentoo, Redhat,判断Linux发行版所处理主流发行系列:
  如果为fedora, centos, redhat,就显示RedHat;
  [ $1 == fedora -o $1 == centos -o $1 == redhat ]
  如果为suse, opensuse,就显示为SUSE;
  如果为ubuntu, mint, debian,就显示为Debian;
  否则,显示为其它或无法识别;
  写一个脚本,其可以接受三个参数,最后一个参数为文件名,但参数可变化,形如:
  script.sh -a MageEdu /magedu.com/scripts/test1.sh
  script.sh -d 2013-07-19 /magedu.com/scripts/test1.sh
  script.sh -D 'some infomation' /magedu.com/scripts/test1.sh
  此脚本能够创建/magedu.com/scripts/test1.sh文件,并且,如果给出了-a MageEdu,则文件前两行为:
  #!/bin/bash
  # Author: MageEdu
  如果给出了-d 2013-07-19,则文件前两行为:
  #!/bin/bash
  # Date: 2013-07-19
  如果给出了-D "some infomation",则文件前两行为:
  #!/bin/bash
  # Description: some infomation
  其它任何参数,均提示错误并退出;
  进一步:如果没有退出,则使用vim打开此文件,并使用光标默认处于最后一行;
  再进一步:保存退出后,如果文件有语法错误提示用户有错误;
  更进一步:如果没有语法错误,则给些文件赋予执行权限;
  a.sh -a mageedu /tmp/test.sh
  #!/bin/bash
  # Author: mageedu
  a.sh -d 2013-07-19 /tmp/test.sh
  #!/bin/bash
  # Date: 2013-07-19
  a.sh -D "test script" /tmp/test.sh
  #!/bin/bash
  # Description: test script
  mkscript
  #!/bin/bash
  if [ $# -ne 3 ]; then
  echo "the number of arguements is wrong."
  exit 4
  fi
  echo '#!/bin/bash' >> $3
  if [ $1 == '-a' ]; then
  echo "# Author: $2" >> $3
  elif [ $1 == '-d' ]; then
  echo "# Date: $2" >> $3
  elif [ $1 == '-D' ]; then
  echo "# Description: $2" >> $3
  else
  echo "Unknown option, ignore it."
  rm -f $3
  exit 5
  fi
  vim + $3
  if bash -n $3 &> /dev/null; then
  chmod +x $3
  else
  echo "Syntax wrong in $3."
  fi
  bash测试之文件测试:
  操作符 文件路径
  -f: 测试其是否为普通文件,即ls -l时文件类型为-的文件;
  -d: 测试其是否为目录文件,即ls -l时文件类型为d的文件;
  -e: 测试文件是否存在;存在为真,否则为假;
  -r: 测试文件对当前用户来说是否可读;
  -w: 测试文件对当前用户来说是否可写;
  -x: 测试文件对当前用户来说是否可执行;
  -s: 测试文件大小是否不空,不空则真,空则假;
  如果/tmp/test10不存在,就创建之;
  if [ ! -e /tmp/test10 ]; then
  mkdir /tmp/test10
  fi
  短路操作:只要前半段已经可以决定最终结果,后半段就不再运算;
  与运算:
  真 && 真 = 真
  真 && 假 = 假
  假 && {真|假} = 假
  或运算:
  假 || 0 = 0
  假 || 1 = 1
  真 ||=1
  [ -e /tmp/test10 ] || mkdir /tmp/test10
  id $UserName &> /dev/null || useradd $UserName

  !>  id $UserName &> /dev/null && echo "$UserName exists." || useradd $UserName
  例子:给定一个路径,判断
  如果为普通文件,显示之;
  如果为目录,显示之;
  否则,说无法识别;
  #!/bin/bash
  #
  if [ ! -e $1 ]; then
  echo "No such file."
  exit 7
  fi
  if [ -f $1 ]; then
  echo "Common file."
  elif [ -d $1 ]; then
  echo "Directory."
  else
  echo "Unknown file."
  fi
  bash的特殊参数:$0: 脚本名称;
  /tmp/script.sh
  basename $0
  写一个脚本:可以接受一个参数,其使用形式如下:
  script.sh {start|stop|restart|status}
  如果参数为start,创建空文件/var/lock/subsys/script,并显示“Starting script successfully.”;
  如果参数为stop,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;
  如果参数为restart,则删除文件/var/lock/subsys/script后重新创建,并显示“Restarting script successfully.”;
  如果参数为status,那么:
  如果/var/lock/subsys/script文件存在,则显示为“script is running.”
  否则,则显示为“script is stopped.”
  其它任何参数:则显示“script.sh {start|stop|restart|status}”
  进一步:修改start的机制为:
  如果参数为start,且/var/lock/subsys/script文件不存在,则创建空文件/var/lock/subsys/script,并显示“Starting script successfully.”;
  否则,显示“script is already running.”
  进一步:修改stop的机制为:
  如果参数为stop,且/var/lock/subsys/script文件存在,则删除文件/var/lock/subsys/script,并显示“Stop script finished.”;
  否则,显示“script is stopped yet.”
  SysV网络服务脚本:
  # service network restart
  # /etc/rc.d/init.d/network start
  # /etc/init.d/network start
  #!/bin/bash
  #
  SvcName=`basename $0`
  LockFile="/var/lock/subsys/$SvcName"
  if [ $# -lt 1 ]; then
  echo "Usage: $SvcName {start|stop|restart|status}"
  exit 3
  fi
  if [ $1 == 'start' ]; then
  if [ -e $LockFile ]; then
  echo "$SvcName is running."
  else
  touch $LockFile &> /dev/null
  echo "Starting $SvcName successfully."
  fi
  elif [ $1 == 'stop' ]; then
  if [ -e $LockFile ];then
  rm -f $LockFile &> /dev/null
  echo "Stopping $SvcName finished."
  else
  echo "$SvcName is stopped yet."
  fi
  elif [ $1 == 'restart' ]; then
  rm -f $LockFile &> /dev/null
  touch $LockFile &> /dev/null
  echo "Restarting $SvcName successfully."
  elif [ $1 == 'status' ]; then
  if [ -e $LockFile ]; then
  echo "$SvcName is running."
  else
  echo "$SvcName is stopped."
  fi
  else
  echo "Usage: $SvcName {start|stop|restart|status}"
  exit 4
  fi
  字符串测试:
  >
  <
  ==
  !=
  -z
  -n
  =~:模式匹配检测;
  文件测试:
  -e
  -f
  -d
  -r
  -w
  -x
  -s
  测试条件的逻辑组合:组合测试
  与:-a
  或:-o
  非:!
  与:&&
  或:||
  非:!
  if [ $# -gt 1 -a $# -lt 10 ]

  if>  练习:写一个脚本
  给定一个文件:
  如果是一个普通文件,就显示之;
  如果是一个目录,亦显示之;
  否则,此为无法识别之文件;
  File=
  if [ -f $File ]; then
  echo
  elif [ -d $File ]; then
  echo
  else
  echo
  fi
  判断某目录中所有文件的类型:
  for File in /var/log/*; do
  if [ -f $File ]; then
  echo
  elif [ -d $File ]; then
  echo
  else
  echo
  fi
  done
  bash的编程之case语句:用法格式
  case 变量引用(${}) in
  value1)
  语句1
  语句2
  ...
  ;;
  value2)
  语句1
  语句2
  ...
  ;;
  value3)
  语句1
  语句2
  ...
  ;;
  *)
  语句1
  语句2
  ...
  ;;
  esac
  #!/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=$?
  ;;
  *)
  echo "Usage: `basename $0` {}"
  exit 6
  ;;
  esac
  [ $RetVal -eq 0 ] && echo "Backup etc finished.($Com)."
  case语句解决上一个服务脚本的问题:
  #!/bin/bash
  #
  SvcName=`basename $0`
  LockFile=/var/lock/subsys/$SvcName
  if [ $# -lt 1 ]; then
  echo "Usage: $SvcName {start|restart|stop|status}"
  exit 5
  fi
  case $1 in
  start)
  touch $LockFile
  echo "Starting $SvcName finished." ;;
  stop)
  rm -f $LockFile
  echo "Stopping $SvcName finished." ;;
  restart)
  rm -f $LockFile
  touch $LockFile
  echo "Restarting $SvcName finished." ;;
  status)
  if [ -e $LockFile ]; then
  echo "$SvcName is running..."
  else
  echo "$SvcName is stopped..."
  fi
  ;;
  *)
  echo "Usage: $SvcName {start|restart|stop|status}"
  exit 6
  esac
  练习:判断当前Linux发行版是RedHat, Fedora, CentOS还是其它。
  方法:取得/etc/issue文件第一行的第一个单词后进行比较;
  bash如何与用户交互:bash内置命令, read
  -p "prompt":提示信息
  -t #: 超时秒数
  例子:
  #!/bin/bash
  #
  read -p "Do you agree ?: " YesNo
  case $YesNo in
  y|Y|es)
  echo "Agreed, proceed." ;;
  n|N|o)
  echo "Disagreed, can't proceed." ;;
  *)
  echo "Invalid input." ;;
  esac
  例子:写一个脚本
  1、显示如下菜单给用户:
  m|M) show memory usages;
  d|D) show disk usages;
  q|Q) quit
  2、如果用户选择了第一项,则显示内存使用信息;
  如果选择了第二项,则显示磁盘挂载及使用相关信息;
  如果是第三项,退出,并显示选择退出;
  其它任何内容,均说明错误选项;
  #!/bin/bash
  cat
页: [1]
查看完整版本: shell脚本之判断 if,elif, case