Shell 条件测试语法
test 测试表达式 | 利用test命令进行条件测试表达式,test命令与测试表达式之间至少有一个空格 |
[ 测试表达式 ] | 通过[ ] 中括号进行条件测试表达式,[] 中括号边界与测试表达式之间至少有一个空格 |
[[ 测试表达式 ]] | 通过[[ ]] 双中括号进行条件测试表达式,[[ ]] 双中括号与测试表达式之间至少有一个空格 |
((测试表达式)) | 通过(( )) 双小括号进行条件测试表达式,(( )) 双小括号两端不需要空格 ,常用于整数对比 |
&&,||,<,>
等操作符可用于双中括号[[ ]]
中,但不能应用于[ ]
中
在
[ ]
中一般用-a,-o,-lt,-gt
来代替
符号说明
(( ))
数值比较,运算 C语言
[[ ]]
条件测试,支持正则
$(( ))
整数运算
$[ ]
整数运算
$( )
命令替换 shell会先执行括号的cmd,然后将结果作为变量进行替换,替换只能替换标准输出,错误输出不能替换。
${ }
Shell中变量的原形,用于限定变量名称的范围,并且支持通配符
[ ]
条件测试
( )
重新开一个子shell然后执行,最后一个命令可以不用分号,第一个命令和左边括号不必有空格
{ }
在当前shell里执行,最后一个命令要用分号,第一个命令和左括号之间必须有一个空格
Shell 测试表达式
文件测试表达式
符号 | 功能 |
-d 文件 | 文件存在且为目录则为真 |
-f 文件 | 文件存在且为普通文件则为真 |
-e 文件 | 文件存在则为真,不辩别是目录还是文件 |
-s 文件 | 文件存在且文件大小不为0则为真 |
-r 文件 | 文件存在且可读则为真,与执行脚本的用户权限也有关 |
-w 文件 | 文件存在且可写则为真,与执行脚本的用户权限也有关 |
-x 文件 | 文件存在且可执行则为真,与执行脚本的用户权限也有关 |
-L 文件 | 文件存在且为链接文件则为真 |
f1 -nt f2 | 文件f1比文件f2新则为真,根据文件的修改时间计算 |
f1 -ot f2 | 文件f1比文件f2旧则为真,根据文件的修改时间计算 |
字符串测试表达式
符号 | 参数 | 功能 |
-z | s1 | 如果字符串s1的长度为0,则测试条件为真 |
-n | s1 | 如果字符串s1的长度大于0,则测试条件为真 |
sl | 如果字符串s1不是空字符串,则测试条件为真 |
=或== | s1=s2 | 如果s1等于s2,则测试条件为真,“=”前后应有空格 |
!= | s1!=s2 | 如果s1不等于s2,则测试条件为真 |
< | s1 | 如果按字典顺序s1在s2之前,则测试条件为真 |
> | s1>s2 | 如果按自定顺序s1在s2之后,则测试条件为真 |
- 对于字符串的比较,一定要将字符串
加引号
后再比较。如[ -n "$string" ]
=
与!=
可用于判断两个字符串是否相同- 字符串比较的时候,可以加一个x,比如:
if [ "$test"x = "test"x ]; then
- 使用单个等号
- 注意到等号两边各有一个空格:这是unix shell的要求
- 当
$test
为空的时候,上面的表达式就变成了x = testx,显然是不相等的。 - 如果没有这个x,表达式就会报错:[: =: unary operator expected
整数操作符
-eq,-ne等比较符只能用于数字比较,有字符也会先转换成数字然后进行比较
在[ ]和test中使用 | 在[[ ]]和(( ))中使用 | 说明 |
-eq | ==或= | 等于,全拼为equal |
-ne | != | 不等于,全拼为not equal |
-gt | > | 大于,全拼为greater than |
-ge | >= | 大于等于,全拼为greater equal |
-lt | < | 小于,全拼为less than |
-le | <= | 小于等于,全拼为less equal |
逻辑操作符
在[ ]和test中使用 | 在[[ ]]和(( ))中使用 | 说明 |
-a | && | and(与),两端都为真,则结果为真 |
-o | || | or(或),两端有一个为真,则结果为真 |
! | ! | not(非),两端相反,则结果为真 |
测试表达式的区别总结
测试表达式符号 | test | [ ] | [[ ]] | (( )) |
边界是否需要空格 | 需要 | 需要 | 需要 | 不需要 |
逻辑操作符 | !、-a、 -o | !、-a、 -o | !、&&、|| | !、&&、|| |
整数比较操作符 | -eq、-ne、-lt、-gt、-ge、-le | -eq、-ne、-lt、-gt、-ge、-le | -eq、-ne、-lt、-gt、-ge、-le或=、!=、<、>、>=、<= | =、!=、<、>、>=、<= |
字符串比较操作符 | =、==、!= | =、==、!= | =、==、!= | =、==、!= |
是否支持通配符 | 不支持 | 不支持 | 支持 | 不支持 |
Shell 条件判断之if语句
单分支 IF 条件语句
语法格式
if [ 条件判断式 ];then 条件成立时,执行的程序 fi
if
语句使用fi
结尾,和一般语言使用大括号结尾不同[ 条件判断式 ]
就是使用test命令判断,所以中括号和条件判断式之间必须有空格
then
后面跟符号条件之后执行的程序,可以放在[ ]
之后,用;
分割。也可以换行写入,就不需要;
了
判断vda1磁盘使用率是否大于90%,如果大于90%,则输出"磁盘已满",反之,则没有输出
#!/usr/bin/env bash disk_check=$(df -h | grep vda1 | awk '{print $(NF - 1)}' | awk -F '%' '{print $1}') if (( "${disk_check}" > "90" )); then echo "磁盘已满" fi
双分支语句
语法格式
if [ 条件判断式 ];then 条件成立时,执行的程序 else 条件不成立时,执行的另一个程序 fi
判断vda1磁盘使用率是否大于90%,如果大于90%,则输出"磁盘已满",反之,则输出当前磁盘使用率
#!/usr/bin/env bash disk_check=$(df -h | grep vda1 | awk '{print $(NF - 1)}' | awk -F '%' '{print $1}') if (( "${disk_check}" > "90" )); then echo "磁盘已满" else echo "vda1当前使用率为: ${disk_check}%" fi
多分支语句
语法格式
if [ 条件判断式1 ] then 当条件判断式1成立时,执行程序1 elif [ 条件判断式2 ] then 当条件判断式2成立时,执行程序2 ...省略更多条件.... else 当所有条件都不成立,最后执行此程序 fi
通过用户输入的数字来判断年龄所在阶段
#!/usr/bin/env bash read age if (( "${age}" <= "2" )); then echo "婴儿" elif (( "${age}" >= "3" && "${age}" <= "8" )); then echo "幼儿" elif (( "${age}" >= "9" && "${age}" <= "17" )); then echo "少年" elif (( "${age}" >= "18" && "${age}" <="25" )); then echo "成年" elif (( "${age}" >= "26" && "${age}" <= "40" )); then echo "青年" elif (( "${age}" >= "41" && "${age}" <= "60" )); then echo "中年" else echo "老年" fi
Shell 条件判断之case语句
case 语句和 if…elif…else 语句一样都是多分支条件语句,不过和多分支 if 条件语句不同的是,case 语句只能判断一种条件关系,而 if 语句可以判断多种条件关系。
语法格式
case 变量名 in 值1) 如果变量的值等于值1则执行指令1 ;; 值2) 如果变量的值等于值2则执行指令2 ;; 值3) 如果变量的值等于值3则执行指令3 ;; *) 如果变量的值不等于以上列出的任何值则执行默认指令 esac
case 语句的使用总结
- case 语句比较适合变量值较少且为固定的数字或字符串集合情况,比如变量的值是已知固定的start/stop/restart等元素,那么采用case语实现就比较适合
- case主要是写服务的启动脚本,一般情况下,传参不同且具有少量的字符串,其适用范围窄
- if就是取值判断、比较、应用比case更广。几乎所有的case语句都可以用if条件语句实现
- case语句就相当于多分支的if/elif/else语句,但case语句的优势是更规范
当用户输入对应的数字选择水果的时候,告诉他选择的水果是什么,并给水果单词加上一种颜色
#!/usr/bin/env bash cat <<EOF 1.apple 2.pear 3.banana 4.cherry EOF read -p "请输入您的选择:" num red="\033[31m" green="\033[32m" yewllo="\033[33m" blue="\033[34m" tailer="\033[0m\n" case $num in 1) printf "${red} apple ${tailer}" ;; 2) printf "${green} pear ${tailer}" ;; 3) printf "${yewllo} banana ${tailer}" ;; 4) printf "${blue} cherry ${tailer}" ;; *) printf "${blue} Usage:$0 {1|2|3|4} ${tailer}" exit 1 esac