Shell脚本中的条件执行 gaunthan Posted on Jul 12 2016 ? ShellScript ? > 条件执行是指如果满足某些条件才执行代码。如果没有条件执行,则只能逐条执行命令。如果shell脚本能对系统状态以及进程的环境变量进行测试,则能实现更强大的功能。 ## if/then shell语法使用方括号来进行测试,并使用`then`和`fi`语句,作用与C/C++中的花括号是一样的: ```shell if [ condition ] then statement(s) fi ``` 除了`then`之后的换行符,所有换行都是必需的,或者**使用分号代替**。`[`和`]`中的空格也是必需的。所以,上面的代码可以压缩为: ```shell if [ condition ]; then statement(s);fi ``` 常见的用法是使用分号将then与if放置在一行,即: ```shell if [ condition ]; then statement(s) fi ``` ## else else语句将在condition不成立时执行。 ```shell if [ condition ]; then statement for when the condition is true else statement for when the condition is false fi ``` ## elif elif结构允许为if语句的else部分添加条件测试。它是else if的缩写,以更简明的写法来表示else与if这一连串行为。elif易写、易读,最重要的是便于调试。 ## test `test`本身是一个程序,通常作为shell的内置命令。所以尽管系统上一般都会有`/usr/bin/test`,但它不会被调用,因为首先找到的是shell的内置命令。`test`的另一个名称为`[`。当调用`[`时,它需要一个`]`作为其参数,但如果不使用`]`,`[`也能起到同样的作用。 ### 测试标志 |标志|作用|备注| |--|--|--| |-e|测试文件是否存在|-a标志与此具有相同作用| |-f|测试文件是否存在且为常规文件| |-b|测试文件是否为块设备|块设备的驱动对象是像硬盘这样的按块进行操作的设备| |-c|测试文件是否为字符设备|字符设备的驱动对象是可以向其读写字符的设备,如终端或者/dev/random虚拟设备| |-L|测试文件是否为符号链接|-h标志与此具有相同作用。常规文件的链接(硬链接)也能通过-f测试,块设备的链接能通过-b测试| |-d|测试文件是否为目录文件| |-S|测试文件是否为套接字| |-p|测试文件是否为命名管道| |-r|测试文件是否可读| |-w|测试文件是否可写| |-x|测试文件是否可执行| |-O|测试文件是否属于当前用户ID| |-G|测试文件是否属于当前用户组ID| |-g|测试文件是否设置了sgid位| |-u|测试文件是否设置了suid位| |-s|测试文件是否存在且不为空| |-N|检测文件自从上次读取后是否被修改| ### 文件比较测试 test命令还能对文件进行一些基本的比较操作。`-ef`比较两个文件是否为同一文件系统中相同inode节点的硬链接。 `-nt`与`-ot`用于比较两个文件的修改时间(mtime)。如果文件的时间戳相同,则比较将返回假;如果某个文件不存在,则返回真;如果两个文件都不存在,则返回假。 ### 字符串比较测试 由于测试的字符串有可能会是空字符串,所以需要用引号将变量名引用起来。否则当字符串为空字符串时,将引起语法错误。 有4种符号用于字符串的测试。可以测试字符串是否相等,以及按照字母表测试某个子串是否排在另一个之前: * `=`或`==`,用于测试字符串是否相等,建议使用前者:  * `\<`与`\>`,用于比较字符串大小:  * `!=`,用于测试字符串是否不等:  另外还有一些用于字符串测试的标志: |标志|功能| |--| |-z|测试字符串长度是否为0| |-n|测试字符串长度是否不为零| ### 正则表达式测试 bash 3新增的一个特性是`=~`操作符,它与perl中`=~`符号的作用非常相似。它将右边的内容当成扩展的正则表达式,所以以前需要使用perl、sed或grep才能完成的一些任务,现在bash就能完成。这意味着可以通过`[[ $pkgname =~ .*\.deb ]]`来查找匹配模式`*.deb`的文件名。注意要使用双方括号语法`[[ ... ]]`。 ### 数值测试 有六种数值比较测试可供使用: |标志|定义| |--| |-eq|如果两数相等,返回真| |-ne|如果两数不相等,返回真| |-lt|用于测试两个数的小于关系| |-gt|用于测试两个数的大于关系| |-le|用于测试两个数的小于或等于关系| |-ge|用于测试两个数的大于或等于关系| 例子如下:  ### 组合测试 可以使用`&&`和`||`操作符来将测试组合起来。它们分别实现测试的逻辑与、逻辑或。 ## case case提供了一种更加清晰、易于编写以及更具可读性的代替if/then/else的结构,尤其是在对多个值进行测试的情况下。case使用`;;`来终止语句,表示不再执行其他语句。如果使用`;;&`终止语句,则还要匹配接下来的所有模式。如果使用`;&`终止语句,则认为接下来的模式已经配对。这种特性是bash shell特有的,如果需要编写可移植脚本,不要使用该特性。常规的case语句在第一次配对之后就会终止。 基本的case块如下: ```shell #!/bin/sh # case.sh read -p "Please input your choice:" choice case $choice in 1) echo "You chose 1.";; 3) echo "You chose 3.";; 6) echo "You chose 6.";; *) echo "Such choice does not exist." esac ``` 赏 Wechat Pay Alipay Shell脚本中的变量 Shell脚本中的循环