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脚本编程大全

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,425评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,058评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,186评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,848评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,249评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,554评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,830评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,536评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,239评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,505评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,004评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,346评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,999评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,060评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,821评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,574评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,480评论 2 267