之前所说的脚本都是按所有命令顺序依次执行的,但有时我们并非希望如此。所谓结构化命令(structured command)是指对脚本中的命令施加一些逻辑流程控制的命令,比如根据条件跳过某些命令等。常见的有if判断语句、for循环语句等,而作为最基本的结构化命令,先了解学习下if语句~
基本格式 if-then语句
#!/bin/bash
if pwd
then
echo "It worked"
fi
结合上面的例子,要点如下:
- 1、if判断条件:其它编程语言一般根据等式结果(TRUE/FALSE),进行判断选择。如上示例,shell中是根据一个命令,标准是该命令是否成功执行,即退出状态码是否为0。若成功执行(退出状态码为0),则执行then语句的条件。
值得注意的是执行该脚本时,命令
pwd
也会显示输出结果;若命令不能运行,也会输出报错信息,再显示then语句的输出(如果有的话)。还有就是shell也支持等式判断,需要设置特殊格式,见下面的学习。
- 2、 then的书写一般另起一行,也有人习惯与if同行,用分号
;
隔开,如下:
if pwd; then
echo "It worked"
fi
- 3、进行判断而执行的语句,一般用tab键提前,以示该命令是属于if语句里的;此外也可以不止一条命令,可见下面的例子。
- 4、fi 标志if语句的结束。(才反应过来,就是if倒过来了,哈哈~)
衍生一、if-then-else
- 针对判断语句是否为0,分别有then命令,和else命令对应。
#!/bin/bash
testuser=NoSuchUser
#
if grep $testuser /etc/passwd #注意grep的用法
then
echo "The bash files for user $testuser are:"
ls -a /home/$testuser/.b* # -a参数表示显示所有文件,包括隐藏文件
else
echo "The user $testuser does not exist on this system."
echo #生成空行
fi
上述脚本代码演示了查找系统中是否还有某一用户,分别对应了有、没有的两种返回结果。
衍生二、嵌套if
- 即在then或else命令里,再次执行一个或多个if语句。
- 比如判断是否存在某一用户,若不存在,那是否存在相关目录:
写法1:普通直接嵌套
#!/bin/bash
testuser=NoSuchUser
#
if grep $testuser /etc/passwd #注意grep的用法
then
echo "The user $testuser exists on this system."
else
echo "The user $testuser does not exist on this system."
if ls -d /home/$testuser # -d参数表示只显示目录名
then
echo "However,$testuser has a directory" #当然也可以在下面补充一种 else 情况
fi
fi
写法2:elif嵌套
#!/bin/bash
testuser=NoSuchUser
#
if grep $testuser /etc/passwd #注意grep的用法
then
echo "The user $testuser exists on this system.
elif ls -d /home/$testuser # -d参数表示只显示目录名
then
echo "The user $testuser does not exist on this system."
echo "However, $testuser has a directory" #当然也可以在下面补充一种 else 情况
fi #注意此时只有一个 fi 结尾
我个人还是觉得第一种写法,更有逻辑性,但可能不是那么简洁。
衍生三、[ ]
测试条件
- 上面提到,if的判断标准一般是命令的退出状态码。此外shell也提供了其它测试条件,比如
test
命令(详见p238)、[ ]
测试,我觉得后者更实用,下面学习下~ - 此处强调一下,[ condittion ]的写法,括号内两边要各保留一个空格,否则会报错。
1、数值比较
常见比较符号有:
-
-eq
等于 -
-ge
大于等于 -
-gt
大于 -
-le
小于等于 -
-lt
小于 -
-ne
不等于
#!/bin/bash
#
value1=10
value2=11
#
if [ $value1 -gt 5 ] #判断是否大于5,注意保留空格
then
echo "The test $value1 is greater than 5"
fi
#
if [ $value1 -eq $value2 ]
then
echo "The values are equal"
else
echo "The values are different"
fi
如果涉及高级的数学表达式(如幂运算等),可使用
(( ))
,详见p256
2、字符串比较
常见的比较符号有=
字符串相等;!=
字符串不等;此外还有字符串大小,以及长度是否为0的判断,详见p242。这里以字符串是否不等为例:
#!/bin/bash
#
testuser=anyuser
#
if [ $USER != $testuser ]
then
echo "you are not $testuser"
else
echo "Welcome testuser"
fi
关于字符串比较,可定义正则表达式来匹配字符串值,要加上双方括号
[[ ]]
,详见p256
3、判断对象类型(文件/目录)、权限、属组等
教材作者说,这种测试是编程中最为强大的,用的最多的比较形式,可我觉得对于我以后用的机会不会很多吧~,简单学习下(详见246)。常见的比较符号有:
-
-e file
检查file是否存在; -
-d file
检查file是否存在,且为一个目录; -
-f file
检查file是否存在,且为一个文件; -
-r file
检查file是否存在,且可读。
#!/bin/bash
# Check if either a directory or a file exists
#
item_name=$HOME
echo
echo "The item being checked: $item_name"
echo
#
if [ -e $item_name ] #判断是否存在该对象
then
echo "The item, $item_name, does exist."
echo "But is it a file?"
echo
#
if [ -f $item_name ] #判断是否为文件
then
echo "Yes, $item_name is a file."
#
else
echo "No, $item_name is not a file"
fi
#
else
echo "The item, $item_name, does not exist."
fi
上述代码就对象是否存在,及是否为文件。在then命令里使用了嵌套if语句。
注意一下上述代码第2-4行,优雅的程序员~~
以上就是关于if语句的简单介绍,教材最后还提到了
case
命令补充了if语句用法,详见p257。下一次学一下循环语句的用法。
参考教材为《Linux命令行与shell脚本编程大全》