Linux 命令行与 shell 脚本编程大全 12 使用结构化命令

介绍可以对 shell 脚本中的命令进行逻辑流程控制的结构化命令( Structured Command )

更多精彩

导览

  1. 使用结构化命令可以改变 shell 脚本的正常执行流程
  2. if-then 语句是最基本的结构化命令,允许执行一个命令,并根据命令的输出情况决定后续输出
  3. if-then-else 语句是 if-then 语句的扩展版,可以将命令执行后的是否情况进行完整覆盖
  4. if-then-elif-then 语句是 if-then 语句的升级版,相当于把两个 if-then 语句进行嵌套
  5. if-then-elif-then-else 语句是 if-then 语句的终极版,相当于在多个 if-then 语句嵌套后再提供一个最坏情况下的缺省判断
    • 这其中的 elif-then 部分可以无限嵌套
  6. test 命令可以让 if-then 语句实现条件判断,方括号( [ condition ] )test 命令的简写版
  7. 双括号 可以实现覆盖 test 命令基本功能的前提下,进行更多的高级数学运算,例如 val++!val
  8. 双方括号 可以实现覆盖 test 命令基本功能的前提下,进行更多的高级字符串比较,其实就是进行字符串的正则表达式匹配
  9. case 命令可以代替嵌套过于复杂的 if-then 语句,让语法逻辑更清晰明了

12.1 使用 if-then 语句

  1. if-then 语句是最基本的结构化命令,基本语法如下
    • 如果 if 后的 command 退出状态码是 0 ,则会执行 then 后面的 command
if command
then
  command
fi
  1. 写一个简单的例子演示一下,如下图

12.2 if-then-else 语句

  1. if-then-else 语句是在 if-then 语句不满足条件无法执行时,提供 else 语句执行另外一部分命令,基本语法如下
    • 如果 if 的条件不满足,会执行 else 后面的 command
if command
then
  command
else
  command
fi
  1. 写一个简单的例子演示一下,如下图

12.3 嵌套 if

  1. if-then-elif-then 语句是在 if-then 语句不满足条件,但又不想直接通过 else 执行另一部分命令时,可以通过 elif 再做一次判断,基本语法如下
    • 如果 if 的条件不满足,会再判断一次 elif 的条件,满足则执行 elif 后续 then 中的 command ,否则什么都不做
if command
then
  command
elif command
then
  command
fi
  1. if-then-elif-then 语句还可以和之前的 else 做结合,最终写成 if-then-elif-then-else 的版本
  2. 在一个完整的 if-then-elif-then-else 的语句中,ifelse 都只能出现一次,但 elif 可以在中间出现无数次
    • 但过多的 if 结构嵌套会导致 shell 的逻辑判断非常混乱,所以不建议写这种链式操作
  3. 写一个简单的例子演示一下,如下图
    • elif 中用到了后续会学到的条件判断,不用慌

12.4 test 命令

  1. if-then 语句无法直接获取命令退出状态码之外的条件,但是可以通过 test 命令实现这种需求
  2. 如果 test 命令列出的条件成立,test 命令就会返回退出状态码 0
  3. test 命令和 if-then 语句结合使用的语法如下
if test condition
then
  command
fi
  1. 如果 test 命令后面不使用任何条件,默认会返回退出状态码 1 ,如下图
  2. 写一个简单的例子演示一下,如下图
    • user 不是空的时候,输出了 if-then 后面的语句
    • gender 是空的时候,输出了 else 后面的语句
  3. test 命令其实还提供了一种简写形式,语法如下
    • 使用一对中括号将测试条件包裹,就可以完美替代掉 test 命令的显式字符
    • 需要注意的是,中括号与测试条件之间必须在首尾添加空格,这是语法强制性要求,不是规范性要求
if [ condition ]
then
  command
fi
  1. 写一个简单的例子演示一下,如下图
    • 测试的内容和上一个例子一样,只是把 test 命令换成了中括号,得到的结果是完全一致的

12.4.1 使用 test 命令进行数值比较

  1. test 命令支持以下列表的数值比较形式
    • 需要注意的是,只能处理整数值,对于浮点数值处理不能
  2. 写一个简单的例子演示一下,如下图

12.4.2 字符串比较

  1. test 命令支持以下列表的字符串比较形式
    • 判断字符串是否相等、长度是否为 0 还比较实用
    • 但是判断字符串的大小就不太实用,而且这个大小比较其实是顺序比较
    • 不光是顺序比较,在 test 命令中直接使用大于号小于号还会导致被误判为 输出重定向输入重定向 ,需要使用转义符才能避免这种误判
    • 所以字符串的大小不止是不实用,还特别难用,这里就不演示了
  2. 写一个简单的例子演示一下,如下图

12.4.3 文件比较

  1. test 命令支持以下列表的文件比较形式

12.4.3.1 使用 -d file 检查目录

  1. 使用 [ -d file ] 可以判断 file 是否存在,并且是目录,如下图

12.4.3.2 使用 -e file 检查对象是否存在

  1. 使用 [ -e file ] 可以判断 file 是否存在,如下图
    • 先通过 [ -e file ] 判断对象是否存在
    • 如果对象存在,再通过 [ -d file ] 判断对象是否为目录,不是目录就是文件

12.4.3.3 使用 -f file 检查文件

  1. 使用 [ -f file ] 可以判断 file 是否为文件,如下图
    • 这个例子和上一个例子的区别就是把第二层判断从 [ -d file ] 改成了 [ -f file ]
    • 然后 thenelse 中的输出进行了对调,得到的结果是一样的

12.4.3.4 使用 -r file 检查文件是否可读

  1. 使用 [ -r file ] 可以判断 file 是否存在,并且可读,如下图

12.4.3.5 使用 -s file 检查空文件

  1. 使用 [ -s file ] 可以判断 file 是否非空,对象不是空的就返回 0 ,否则返回 1 ,如下图

12.4.3.6 使用 -w file 检查文件是否可写

  1. 使用 [ -w file ] 可以判断 file 是否存在,并且可写,如下图

12.4.3.7 使用 -x file 检查文件是否可执行

  1. 使用 [ -x file ] 可以判断 file 是否存在,并且可执行,如下图

12.4.3.8 使用 -O file 检查文件所属用户关系

  1. 使用 [ -O file ] 可以判断 file 是否存在,并且是否属于当前执行脚本的用户,如下图
    • 注意这是大写字母 O ,而不是数字 0

12.4.3.9 使用 -G file 检查文件所属组关系

  1. 使用 [ -G file ] 可以判断 file 是否存在,并且 file 的默认组和当前用户的默认组是否相同,如下图
    • 需要注意的是,这里只会判断两者的默认组是否相同
    • 如果 file 的默认组中当前用户是组成员,但并不是当前用户的默认组,那么检查结果返回的会是 0

12.4.3.10 使用 -nt 和 -ot 检查文件日期

  1. 使用 file1 -nt file2 可以检查 file1 是否比 file2
  2. 使用 file1 -ot file2 可以检查 file1 是否比 file2
  3. 写一个简单的例子演示一下,如下图
    • 需要注意的是,检查的是创建日期
    • 还需要注意的是,这个比较不会自动判断比较对象是否存在

12.5 复合条件测试

  1. if-then 语句后的条件支持两种形式的条件同时判断,形式如下
    • 用法就和 Java 或 JS 等编程语言中一样,不再赘述
[ condition ] && [ condition ]
[ condition ] || [ condition ]
  1. 写一个简单的例子演示一下,如下图

12.6 if-then 的高级特性

12.6.1 使用双括号计算数学表达式

  1. if-then 语句中使用双括号后,可以在双括号中使用多个复杂的数学表达式,例如 val++val--++val--val!val
    • 这些参数对于使用过 Java 或 JS 等编程语言的来说肯定不陌生,但使用起来却不太一样
    • 另外还有一些位运算符,例如 ~&| ,不常用就不多做介绍
  2. 而且双括号并不局限于写在 if 后面的条件判断中,也可以在 then 后面的输出中使用
    • 其实双括号就算不在 if 语句中,也可以直接使用
  3. 同时在双括号中对于大于、小于等操作不需要使用对应的 -gt-lt 操作符,可以直接使用 ><
  4. 写一个简单的例子演示一下,如下图
    • 在 Java 中,num++ 其实是 num=num+1
    • 但在 shell 中,想要实现 num=num+1 的效果必须是 num2=num1++1 ,如果直接写成 num++ 会报错

12.6.2 使用双方括号进行字符串处理

  1. 在双括号中可以实现的高级字符串处理,是指除了能实现 test 命令提供的所有特性外,还能实现 模式匹配( Pattern Matching )
    • 其实就是进行字符串的正则表达式匹配
    • 不是所有的 shell 都支持双方括号
  2. 写一个简单的例子演示一下,如下图

12.7 case 命令

  1. 使用 case 命令可以实现复杂的嵌套 if-then 语句的效果,但逻辑相对 if-then 语句会更清晰,基本语法如下
    • case 语句会将 variable 的值与 in 后面的各种 pattern 进行比较,如何符合,则执行对应的 command
    • 如果所有的 pattern 都不符合,则执行最后星号中的 command
    • 需要注意的是,如果一个条件后面有多个语句,并不是每个语句最后都需要使用 双分号( ;; ) ,而是只需要在该条件的最后一个语句使用即可
case variable in
pattern1 | pattern2 ) 
  command1
  command2;;
pattern3 ) 
  command;;
* ) 
  default command;;
esac
  1. 写一个简单的例子演示一下,如下图
发布了418 篇原创文章 · 获赞 47 · 访问量 20万+

猜你喜欢

转载自blog.csdn.net/asing1elife/article/details/103784091