shell 脚本之条件测试和流程结构

条件测试

每个命令结束后,都有返回一个结束状态值,值为0表示执行成功,非0表示失败。条件测试就是以状态返回值的真假值作为判断依据:值为0判断为真,非0判断为假。

条件测试的写法

  • 执行一个命令,可以包括管道命令。例如:

if  grep  -q  "rm"  fn.sh;  then
     echo "find rm command."
else
     echo  "not found ."
fi
  • 传回某一命令执行结果的相反值:! command!与命令之间用空格分开。

if  !  grep  -q  "rm"  fn.sh;  then
     echo  "not found ."
else
     echo "find rm command."
fi
  • 使用符合命令:(( expression ))。如果expression的值不为0,则传回真值(0),否则传回假值(1)。

  • 使用Bash关键字[[]]组成的式子:[[ 判断式 ]]注意:[[ 的后面、]]的前面都要有空格。


if  [[ str > xyz ]];  then
     echo "str bigger than  xyz."
else
     echo "str not bigger than  xyz."
fi
  • 使用内置命令test: test 判断式

if  test "str" \> "xyz";  then
     echo "str bigger than  xyz."
else
     echo "str not bigger than  xyz."
fi
  • 使用内置命令:[][]test的用法是相同的,可以互换。注意:[ 的后面、]的前面都要有空格。

if  [ "str" \> "xyz" ];  then
     echo "str bigger than  xyz."
else
     echo "str not bigger than  xyz."
fi
  • 使用-a, -o进行逻辑组合。-a是逻辑与,-o逻辑或。例如:[ -f filename -a -x filename ],如果filename可读且可执行则为真。

  • 注意:

    • test[]都需要对Bash特殊字符进行转义;而[[]]不需要,<, >, &&, ||都可以在其中自由使用。
    • [[ 判断式 ]]中,如果使用==, !=,且在这两个运算符右边的字符串没有加上单引号或双引号,则==, !=会视为需要匹配该字符串所形成的“样式”,如果匹配,返回0,否则返回1。
    • [[ 判断式 ]]中,=~的右边放置要匹配的样式。样式不能用引号引起,否则不会被当作样式匹配。

条件判断式

文件的条件判断式


判断式                    在什么情况下为真
-a  filename            如果文件存在
-b  filename            如果文件存在,且该文件是块设备文件
-c  filename            如果文件存在,且该文件是字符设备文件
-d  filename            如果文件存在,且该文件是目录
-e  filename            如果文件存在
-f  filename            如果文件存在,且该文件是普通文件
-g  filename            如果文件存在,且该文件设置了set group id 属性
-h  filename            如果文件存在,且该文件是符号链接文件
-k  filename            如果文件存在,且该文件设置了 sticky 属性
-p  filename            如果文件存在,且该文件是管道文件(FIFO)
-r  filename            如果文件存在,且该文件具有可读属性
-s  filename            如果文件存在,且该文件的长度大于0
-t  文件描述符         如果文件描述符是开启的,且链接了一个终端
-u  filename            如果文件存在,且该文件设置了set user id 属性
-w  filename            如果文件存在,且该文件具有可写属性
-x  filename            如果文件存在,且该文件具有可执行属性
-O  filename            如果文件存在,且该文件为游戏的使用者id所拥有
-G  filename            如果文件存在,且该文件为游戏的群组id所拥有
-L  filename            如果文件存在,且该文件是符号链接文件
-S  filename            如果文件存在,且该文件是 socket 文件
-N  filename            如果文件存在,且该文件自上次读取后,曾修改过
file1  -nt  file2         如果fil1比file2新;或file1存在,file2不存在
file1  -ot  file2         如果fil1比file2旧;或file2存在,file1不存在
file1  -ef  file2         如果fil1比file2引用到系统的设备和inode编号

字符串的条件判断式


判断式                    在什么情况下为真
-z  str                     如果字符串长度为0
-n  str                    如果字符串长度不为0
str                         如果字符串长度不为0
str1 == str2           如果两个字符串相同
str1 = str2             如果两个字符串相同
str1 != str2            如果两个字符串不相同 
str1 < str2             如果str1小于str2
str1 > str2             如果str1大于str2

注意:如果<, >出现在test, []中,要进行转义。

数值的条件判断式


判断式                     在什么情况下为真
var1  -eq  var2         var1和var2值相等
var1  -ne  var2         var1和var2值不相等 
var1  -lt  var2           var1的值小于var2的值
var1  -le  var2          var1的值小于等于var2的值
var1  -gt  var2          var1的值大于var2的值
var1  -ge  var2         var1的值大于等于var2的值

流程控制

if 条件判断

完整语法:


if  条件测试1;  then
     cmd1
elif  条件测试2;  then
     cmd2
else
     cmd3
fi

case 条件判断

完整语法


case  待测试项  in
     样式串1)   命令区域1;;
     样式串2)   命令区域2;;
     样式串3)   命令区域3;;
     ... 
     *)   命令区域;;
esac

说明

  • 命令区域可以有多条命令,但最后一条命令必须以;;结束。
  • 样式串可用字符串和通配符组成,默认不区分大小写。
  • 如果样式串行中有几个字符串要对比,用|隔开。|表示或的意思。
  • 样式串可以写成 (样式串行) ,或省略左边的括号,写成 样式串行) 。推荐后者。
  • 样式*)通常放在case最后一个区域,用来捕捉不符合指定样式的其他所有情况。

样式串组成

  • 字符串。
  • 通配符:*表示任意字符串;?表示单个字符。
  • 字符集合:[]
  • 项目分隔符|

打开Bash的选项extglob,还可以支持几种高级样式匹配:shopt -s extglob

  • ?(样式串行):如果符合0或1个括号里的样式串行,算匹配。
  • *(样式串行):如果符合0个以上括号里的样式串行,算匹配。
  • +(样式串行):如果符合1个以上括号里的样式串行,算匹配。
  • @(样式串行):如果符合括号里的样式串行中的一个,算匹配。
  • !(样式串行):只要是不出现在括号里的样式串行,算匹配。

高级样式,除了在case中使用,还可以用在[[]]条件判断中。

for循环

方式1:遍历串行


for  变量  in  串行
do
     commands
done

串行是由字符串组成,彼此用 $IFS 所定义的分割字符隔开。

举例,遍历命令行参数for i in $@,处理当前目录:for f in $(ls .)

方式2:C-style for循环


for  ((初始条件;  终止条件;  改动项))
do
     commands
done

方式3:死循环


for  ((;  1;  ))
do
     commands
done

while 循环

语法:


while  条件测试
do
     cmds
done

while循环搭配输入重定向读取文件内容:


while  read  line
do
     echo  $line
done  <  input_file

until 循环

whlie循环的条件测试是测试真值,until循环是测试假值,值为假则进入循环。

语法:


until  条件测试
do
     cmds
done

select 语句

select命令可建立简易的列表,语法结构和for循环一样。


for  选项变量  in  串行
do
     cmds
done

说明:

  • select命令建立一个选择列表。列表的选项由串行中的各个字段组成。列表提示符号由Bash的内置变量PS3定义,可改变。select会给各个选项一个编号,编号由1开始递增。当用户输入编号,选择其中一项时,该选项的内容就设置给选项变量,键入的编号值放入变量REPLY
  • 用户每输入一次编号,就执行一次命令区域。
  • 命令执行完后,重新执行select命令,再次显示列表。

break, continue

for, while, until, select循环中,可以用break跳出循环,break后面可跟一个层数n(n一定要大于等于1),表示跳出循环的层数;用continue可跳过本次循环。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

This site uses Akismet to reduce spam. Learn how your comment data is processed.