Shell结构化命令(1):控制流

使用if - then - else语句

if - then - else语句类似我们常用的if - else,基本格式:

if command 
then
commands
else
commands
fi

不同于if - else的是:if - else判断条件是否成立依赖truefalse,而if - then语句依赖于ifshell command是否成功执行,即:命令的退出状态码是0

若是0,则then后的命令被执行;若不是0,则else后的命令被执行。fi表示if - then - else语句到此结束。

if - then - else语句也可以像if - else语句一样嵌套使用,基本格式:

if command1 
then
command set 1 
elif command2
then
command set 2 
elif command3 
then
command set 3 
elif command4 
then
command set 4
fi

使用test命令

如果需要if - then - else语句,判断退出状态码之外的条件,如:truefalse,怎么办?解决办法,使用test命令:test condition

关于test命令的描述:

test用于评估表达式,如果它评估结果为true,则会返回退出状态码:0true);否则,返回退出状态码:1false);如果没有表达式,test命令也会返回退出状态码:1false)。

testif - then - else配合:

if test command 
then
commands
else
commands
fi
关于test的同义命令,方括号:[ ]

基本使用格式:

if [ condition ] then
commands
fi

注意:第一个方括号之后和第二个方括号之前必须加上一个空格, 否则就会报错。

布尔逻辑支持:

[ condition1 ] && [ condition2 ] #与运算
[ condition1 ] || [ condition2 ] #或运算
关于test可以判断的三类条件:
  • 数值比较
数值比较 描述
n1 -eq n2 检查n1与n2是否相等
n1 -gen2 检查n1是否大于等于n2
n1 -le n2 检查n1是否小于等于n2
n1 -gt n2 检查n1是否大于n2
n1 -lt n2 检查n1是否小于n2
n1 -ne n2 检查n1是否不等于n2
#! /bin/bash
# 控制流
var1=133
var2=145

if [ $var1 -eq $var2 ] 
then
  echo "$var1 等于 $var2"
elif [ $var1 -ge $var2 ]
then
  echo "$var1 大于等于 $var2"
elif [ $var1 -le $var2 ]
then
  echo "$var1 小于等于 $var2" #脚本输出:133 小于等于 145
elif [ $var1 -lt $var2 ]
then
  echo "$var1 小于 $var2"
elif [ $var1 -gt $var2 ]
then
  echo "$var1 大于 $var2"
elif [ $var1 -ne $var2 ]
then
  echo "$var1 不等于 $var2"
else
  echo "不识别"
fi

exit 0

注意,在test命令中使用浮点数会报错:145.5: integer expression expectedbash shell只能处理整数。

  • 字符串比较
字符串比较 描述
str1 = str2 检查str1和str2是否相等
str1 != str2 检查str1和str2是否不相等
str1 > str2 检查str1是否大于str2
str1 < str2 检查str1是否小于str2
-n str1 检查str1的长度是否非0
-z str1 检查str1的长度是否为0
#! /bin/bash
# 字符串比较
var1="abc"
var2="acb"
var3=""
var4="abc"

if [ -n $var1 ];then
 echo "字符串var1的长度大于0" #执行脚本输出
fi

if [ $var2 ];then
 echo "字符串var2有值"#执行脚本输出
fi

if [ -z $var3 ];then
 echo "字符串var3的长度为0"#执行脚本输出,var3未初始化也会执行
fi

if test $var4 = $var1 ; then
  echo "字符串var4=var1"#执行脚本输出
  if [ $var1 \> $var2 ]; then
   echo "字符串var1 > var2"#执行脚本输出
  elif [ $var1 != $var2 ]
  then
   echo "字符串var1不等于var2"
  else 
   echo "字符串var1小于var2"
  fi
else
  echo "字符串var4!=var1"
fi

exit 0

注意: 大于号和小于号必须转义,否则shell会把它们当作重定向符号,把字符串值当作文件名;大于和小于顺序和sort命令所采用的不同。

  • 文件比较
文件比较 描述
-d file 检查file是否存在并且是个目录
-e file 检查file是否存在
-f file 检查file是否存在并且是个文件
-r file 检查file是否存在并且可读
-w file 检查file是否存在并且可写
-x file 检查file是否存在并且可执行
-s file 检查file是否存在并且非空
file1 -nt file2 检查file1是否比file2新
file1 -ot file2 检查file1是否比file2旧
-O file 检查file是否存在并属当前用户所有
-G file 检查file是否存在并且默认组与当前用户相同

示例:创建一个新的目录,新的文件,写入脚本数据,改变文件的权限,并执行该脚本。

#! /bin/bash
#文件比较
var1="./compare"
var2="wonderful"
if [ -d $var1 ]; then
   echo "${var1}目录存在,"
   if [ -f $var1/$var2 ] && [ -s $var1/$var2 ]
   then
     echo "${var2}文件存在,并且不为空,切换工作区"
     cd ./${var1}
     if [ -x $var2 ]; then
       echo "文件存在,且可执行,内容如下:"
       cat -n $var2
       ./$var2
     else
       echo "文件存在,不可执行,写入脚本"
       ( echo "#! /bin/bash" ) > $var2
       ( echo "echo $(date) 执行 $var1/${var2}脚本成功")>>$var2
       echo -n "修改权限并执行结果"
       chmod u+x $var2
       ./$var2
     fi
   else
   echo "${var2}文件不存在或文件为空"
   cd ./${var1}
      if [ -e $var2 ]; then
          echo "文件存在"
      else
          touch $var2
      fi
   echo "写入'script'到文件 $var2 "
   ( echo "#! /bin/bash" ) > $var2
   ( echo "echo $(date) 执行 $var1/${var2}脚本成功")>>$var2
   echo "改变 $var2 的权限为可执行"
   chmod u+x $var2
   echo "执行${var2}脚本"
   ./${var2}

   fi
else
   echo "${var1}目录不存在"
   echo "创建 $var1 目录"
   mkdir $var1
   echo "切换目录"
   cd $var1
   echo "当前工作目录:$PWD"
   echo "创建空文件:$var2"
   touch $var2
   echo "写入'script'到文件 $var2 "
   ( echo "#! /bin/bash" ) > $var2
   ( echo "echo $(date) 执行 $var1/${var2}脚本成功")>>$var2
   echo "改变 $var2 的权限为可执行"
   chmod u+x $var2
   echo "执行${var2}脚本"
   ./${var2}
fi

使用if - then - else的高级特性

  • 用于数学表达式的双括号
  • 用于高级字符串处理功能的双方括号
双括号

双括号:允许在比较过程中使用高级数学表达式,而test只支持简单的算术比较:gtge...。

注意:可以在if语句中用双括号命令,也可以在脚本中的普通命令里使用来赋值。

基本格式:

(( expression ))

双括号支持的高级数学表达式:

符号 描述
val++、++val 后/前增
val--、--val 后/前减
!、&&、||、 逻辑取反、与、或
~、&、|、>>、<< 按位取反、与、或、右移、左移
** 幂运算

示例:

#! /bin/bash
# 控制流
var=5

if (( $var ** 3 > 100 ));then
   echo "双括号的赋值操作:"
   var1=$var
   (( var = $var ** 3 ))
   echo -n "输出$var1 ** 3的值为: $var" #输出5 ** 3的值为: 125
   echo ""
fi
双方括号

双方括号:该命令针对字符串比较提供的高级特性。
基本格式:

[[ expression ]]

双方括号里的expression可使用test命令中采用的标准字符串比较,同时它还使用test命令没有的特性:模式匹配。
模式匹配使用==,双等号右边的字符串会被视为一个模式。
示例:

#! /bin/bash
# 控制流
if [[ $USER == q* ]]
then
echo "Hello $USER"
else
   echo "匹配失败"
fi

使用case命令

case命令采用模式匹配的方式,进行变量的匹配。
case命令的基本格式:

case variable in
pattern1 | pattern2) #竖线操作符在一行中分隔出多个模式
commands1;;
pattern3)
commands2;;#注意必须要双分号,这是语法的一部分
*) 
default commands;
esac #结束标志

示例:

#! /bin/bash
# 控制流
case $USER in 
*li|*n*)
echo "hello $USER";;
li)
echo "hi li";;
*)
echo "by";;
esac

参考资料:
Linux命令行与shell脚本编程大全

你可能感兴趣的:(Shell结构化命令(1):控制流)