流程控制:if分支结构
摘要:就像其他编程语言,shell脚本程序也提供了分支。
if
举个例子:
x=5
if [ $x = 5 ]; then
echo "x equals 5."
else
echo "x does not equal 5."
fi
if 语句语法如下:
if commands; then
commands
[elif commands; then
commands...]
[else
commands]
fi
commands 是指一系列命令。
退出状态
当命令执行完毕后,命令(包括我们编写的脚本和 shell 函数)会给系统发送一个值,叫做退出状态。这个值是一个 0 到 255 之间的整数,说明命令执行成功或是失败。按照惯例,一个零值说明成功,其它所有值说明失败。Shell 提供了一个参数,我们可以用它检查退出状态。用具体实例看一下:
xuxg@xuxg-ubuntu:~$ ls -d /usr/bin
/usr/bin
xuxg@xuxg-ubuntu:~$ echo $?
0
xuxg@xuxg-ubuntu:~$ ls -d /bin/usr
ls: cannot access '/bin/usr': No such file or directory
xuxg@xuxg-ubuntu:~$ echo $?
2
shell 提供了两个极其简单的内部命令,它们不做任何事情,除了以一个 0 或 1 退出状态来终止执行。True 命令总是执行成功,而 false 命令总是执行失败:
xuxg@xuxg-ubuntu:~$ true
xuxg@xuxg-ubuntu:~$ echo $?
0
xuxg@xuxg-ubuntu:~$ false
xuxg@xuxg-ubuntu:~$ echo $?
1
我们能够使用这些命令,来看一下 if 语句是怎样工作的。If 语句真正做的事情是计算命令执行成功或失败:
xuxg@xuxg-ubuntu:~$ if true; then echo "It's true."; fi
It's true. xuxg@xuxg-ubuntu:~$ if false; then echo "It's true."; fi
xuxg@xuxg-ubuntu:~$
如果 if 之后跟随一系列命令,则将计算列表中的最后一个命令:
xuxg@xuxg-ubuntu:~$ if false;true; then echo "It's true."; fi
It's true. xuxg@xuxg-ubuntu:~$ if true; false; then echo "It's true."; fi
xuxg@xuxg-ubuntu:~$
测试
经常与 if 一块使用的命令是 test。这个 test 命令执行各种各样的检查与比较。它有两种等价模式:
test expression
比较流行的格式是:
[ expression ]
这里的 expression 是一个表达式,其执行结果是 true 或者是 false。当表达式为真时,这个test 命令返回一个零退出状态,当表达式为假时,test 命令退出状态为 1。
文件表达式
以下表达式被用来计算文件状态:
表达式 | 如果下列条件为真则返回 True |
---|---|
file1 -ef file2 | file1 和 file2 拥有相同的索引号(通过硬链接两个文件名指向相同的文件)。 |
file1 -nt file2 | file1 新于 file2。 |
file1 -ot file2 | file1 早于 file2。 |
-b file | file 存在并且是一个块(设备)文件。 |
-c file | file 存在并且是一个字符(设备)文件。 |
-d file | file 存在并且是一个目录。 |
-e file | file 存在。 |
-f file | file 存在并且是一个普通文件。 |
-g file | file 存在并且设置了组 ID。 |
-G file | file 存在并且由有效组 ID 拥有。 |
-k file | file 存在并且设置了它的“sticky bit”。 |
-L file | file 存在并且是一个符号链接。 |
-O file | file 存在并且由有效用户 ID 拥有。 |
-p file | file 存在并且是一个命名管道。 |
-r file | file 存在并且可读(有效用户有可读权限)。 |
-s file | file 存在且其长度大于零。 |
-S file | file 存在且是一个网络 socket。 |
-t fd | fd 是一个定向到终端/从终端定向的文件描述符。这可以被用来决定是否重定向了标准输入/输出错误。 |
-u file | file 存在并且设置了 setuid 位。 |
-w file | file 存在并且可写(有效用户拥有可写权限)。 |
-x file | file 存在并且可执行(有效用户有执行/搜索权限)。 |
字符串表达式
以下表达式用来计算字符串:
表达式 | 如果下列条件为真则返回 True |
---|---|
string | string 不为 null。 |
-n string | 字符串 string 的长度大于零。 |
-z string | 字符串 string 的长度为零。 |
string1 = string2或string1 == string2 | string1 和 string2 相同。单或双等号都可以,不过双等号更受欢迎。 |
string1 != string2 | string1 和 string2 不相同。 |
string1 > string2 | sting1 排列在 string2 之后。 |
string1 < string2 | string1 排列在 string2 之前。 |
警告:当与 test 一块使用的时候,> 和 < 表达式操作符必须用引号引起来(或者是用反斜杠转义)。如果不这样,它们会被 shell 解释为重定向操作符,造成潜在的破坏结果。
整型表达式
下面的表达式用于整数:
表达式 | 如果为真… |
---|---|
integer1 -eq integer2 | integer1 等于 integer2。 |
integer1 -ne integer2 | integer1 不等于 integer2。 |
integer1 -le integer2 | integer1 小于或等于 integer2。 |
integer1 -lt integer2 | integer1 小于 integer2。 |
integer1 -ge integer2 | integer1 大于或等于 integer2。 |
integer1 -gt integer2 | integer1 大于 integer2。 |
更现代的测试版本
目前的 bash 版本包括一个复合命令,作为加强的 test 命令替代物。它使用以下语法:
[[ expression ]]
这里,类似于 test,expression 是一个表达式,其计算结果为真或假。这个 [[ ]] 命令非常相似于 test 命令(它支持所有的表达式),但是增加了一个重要的新的字符串表达式:
string1 =~ regex
如果 string1 匹配扩展的正则表达式 regex,其返回值为真。
[[ ]] 添加的另一个功能是 == 操作符支持类型匹配,正如路径名展开所做的那样。
(( )) - 为整数设计
除了 [[ ]] 复合命令之外,bash 也提供了 (( )) 复合命令,其有利于操作整数。它支持一套完整的算术计算。
(( )) 被用来执行算术真测试。如果算术计算的结果是非零值,则其测试值为真。
结合表达式
通过使用逻辑操作符来结合表达式
操作符 | 测试 | [[ ]] and (( )) |
---|---|---|
AND | -a | && |
OR | -o | || |
NOT | ! | ! |
控制操作符:分支的另一种方法
bash 支持两种可以执行分支任务的控制操作符。&&(AND)和 ||(OR)操作符作用如同复合命令 [[ ]] 中的逻辑操作符。这是语法:
command1 && command2
和
command1 || command2
理解这些操作很重要。对于 && 操作符,先执行 command1,如果并且只有如果 command1执行成功后,才会执行 command2。对于 || 操作符,先执行 command1,如果并且只有如果command1 执行失败后,才会执行 command2。
总结
本章学习了shell编程的if分支结构等内容。