Shell 巩固和复习系列笔记,立个 Flag,之后不定时更新相关工作上可能遇到的 Shell 应用场景。
在 bash 各种条件结构和流程控制结构中都要进行各种测试,然后根据测试结果执行不同的操作,有时也会与if等条件语句相结合,来完成测试判断,以减少程序运行的错误。
执行条件测试表达后通常会返回“真”或“假”,就像执行命令后的返回值为 0 表示真,非 0 表示假一样。
条件测试常用语法
条件测试语法说明语法1:test <测试表达式>利用 test 命令进行条件测试表达式的方法,test 与表达式至少隔一个空格语法2:[ <测试表达式> ]通过[](单括号)进行条件测试表达式的方法,与 test 命令用法相同,边界与表达式至少隔一个空格语法3:[[ <测试表达式> ]]通过[[]](双中括号)进行条件测试表达式的方法,边界与表达式至少隔一个空格语法4:((<测试表达式>))通过(())(双小括号)进行条件测试表达式的方法,一般用于if语句,(())与表达式不需要留空格说明:
语法1中的 test 命令和语法 2 中的[]等价,[[]]为扩展的 test 命令,(()) 常用于算数运算[[]](双中括号)可以使用通配符进行模式匹配,区别于其他语法模式&&、||、!、>、<等操作符可以用于 [[]] 中,但不能应用于 [] 中,在 [] 中一般用 -a、-o、-gt(整数)、-lt(整数)等命令行参数代替操作符整数的关系运算,也可以使用 Shell 的算数运算符 (())test 等价于[] ,三个基本作用就是判断文件、字符串、整数。支持使用与或非将表达式连接起来
test 中可用的比较运算符只有 ==和 != ,两者都用于字符串比较的,不可用于整数比较,整数比较只能使用-eq、-gt这种参数形式,如需要使用大于>或小于<进行字符串的比较,必须加上转义符号如[ ab \< bc ]
[root@aurora study]# test -f test.txt && echo true || echo false true如果 test.txt 文件存在,输出 true,否则输出 false,-f 判断是否为普通文件
test -z “tuzaza” && echo 1 || echo 0如果测试字符串的长度为 0 则输出 1,否则输出 0,-z判断字符串的长度是否为 0
Tips:关于 test 测试表达式的更多知识可以执行man test查看帮助
如果 /home/study/test.txt 文件存在,则输出 1,否则输出 0
[[]] 支持字符串的模式匹配,使用=、~等操作符支持 Shell 的正则表达式,逻辑组合不可以使用 test 的 -o和 -a,而是使用 && 和 ||
字符串比较时把右边当做一个模式(字符串不加双引号,加双引号的字符串被认为是一个文本字符串),如[[ hello==hell? ]]为真
[[ -f /home/study/test.txt ]] && echo 1 || echo 0如果/home/study/test.txt文件存在,则输出1,否则输出0
(())等价于let,都只能对整数进行赋值运算
(())算数表达式的值在if和while判断时不用在前面加$,在echo输出值需要加$,如echo $(( c = a+b+1 ))
使用 let 或 (()) 赋值的时候,也可以使用expr+反引号替代
let a = $b + $c 等价于 a = `expr $b + $c` a=1; let “a<0”; echo $? a=1; ((a<0)); echo $? if((a>0));then echo x greater else; echo x not greater fi常用的文件测试操作符
常用文件测试操作符说明-b文件,b 全拼为 block文件存在且为一个块(设备)文件为真-c文件,c 全拼为 char文件存在且为一个字符(设备)文件为真-d 文件,d 全拼为 directory文件存在且为目录文件为真-f 文件,f 全拼为 file文件存在且为普通文件为真-e 文件,e 全拼为 exist文件存在为真-r 文件,r 全拼为 read文件存在且可读为真-s文件,s 全拼为 size文件存在且其长度大于0为真-S,文件,S 全拼为 Socket文件存在且是一个网络socket为真-s 文件,s 全拼为 size文件存在且大小不为0为真-w 文件,w 全拼为 write文件存在且可写为真-x 文件,x 全拼为 executable文件存在且可执行为真-p 文件,p 全拼为 pipe文件存在且为一个命令管道为真-L 文件,L 全拼为 link文件存在且为链接文件为真f1 -ef f2,ef 全拼为 equal file文件 f1 和 f2 拥有相同的索引号(可判断是否同一文件,硬链接)f1 –nt f2,nt 全拼为 newer than文件 f1 比文件 f2 新则为真,根据文件的修改时间计算f1 –ot f2,ot 全拼为 older than文件 f1 比文件 f2 旧则为真,根据文件的修改时间计算更多关于文件测试操作符可以man test 查看
例子1.不用 if 测试表达式格式
当条件1成立时,同时执行命令1、命令2、命令3。不用 if 测试表达式格式如下:
[ 条件1 ] && { 命令1 命令2 命令3 } [[ 条件1 ]] && { 命令1 命令2 命令3 } 上面的判断语句等价于下面if语句的效果。 if [ 条件 ] then 命令1 命令2 命令3 fi例子2.使用逻辑运算符|| 当条件不成立时,执行大括号内的多条命令,使用逻辑运算符 ||
[ -f /etc ] || { echo 1 echo 2 echo3 }Tips: 如果把上述脚本写在一行内,大括号内的每个命令都需要用分号结尾。如[ -f /etc/services ] && { echo 1; echo 2; echo3; }。虽然案例中的两种方式很简洁,却不如 if 条件语句容易理解。
字符串测试操作符的作用包括:比较两个字符串是否相同、测试字符串的长度是否为 0、字符串是否为NULL等。
注: NULL,是通过 bash 区分零长度字符串和空字符串
字符串测试操作符
常用字符串测试操作符说明-n 字符串若字符串的长度不为0,则为真-z 字符串若字符串的长度为0,则为真“串1” = “串2”若字符串1等于字符串2,则为真“串1” != “串2”若字符串1不等于字符串2,则为真说明:
对于字符串的测试,一定要将字符串加双引号之后再进行比较。如 [ -n “$myvar” ]比较符号(例如=和!=)的两端一定要有空格,否则即使不报错,结果也会出错!=和=可用于两个字符串是否相同例子—字符串测试操作符
[ -n “abc” ] && echo 1 || echo 0 test -n “abc” && echo 1 || echo 0整数二元比较操作符
在[]以及test中使用比较符号在(())和[[]]中使用的比较符号说明-eq== 或 =相等(equal)-ne!=不相等(not equal)-gt>大于(greater than)-ge>=大于等于(greater equal)-lt<小于(less than)-le<=小于等于(less equal)说明:
=和!=也可以在[]中做比较,但在[]中使用包含>和<的符号时,需要用反斜线协议/也可以在 [[]] 中使用包含-gt和-lt的符号比较符号两端也要有空格例子1.二元数字在 [] 中使用 -gt、-le 类符号的比较
[ 2 -gt 1 ] && echo 1 || echo 0 [ 2 -ge 1 ] && echo 1 || echo 0例子2.二次元数字配合不同类型发操作符在[[]]中的比较
[[ 65 < 66 ]] && echo 1 || echo 0例子3.二元数字在 (()) 中的比较
(( 3 > 2 )) && echo 1 || echo 0逻辑操作符
在[]和test中使用的操作符在[[]]和(()中使用的操作符说明-a&&And,与,两端为真结果为真-o||Or,或,两端其一为真,结果为真!!Not,非,两端相反,结果为真例子1.()(单中括号)文件测试
[ -f /etc/host -a -f /etc/services ] && echo 1 || echo 0例子2.数值比较
[ 5 -eq 6 -o 5 -gt 3 ] && echo 1 || echo 0 ((5==6||5>3)) && echo 1 || echo 0不同符号测试表达式test、 []、[[]]、(())的区别
测试表达式符号[]等价于test[[]](())等价于let边界是否需要空格需要需要不需要逻辑操作符!、-a、-o!、&&、||!、&&、||整数二元比较操作符(关系比较操作符)-eq、-gt、lt、-ge、-le 或 >、<-eq、-gt、lt、-ge、-le或=、>、<,不可以使用>=、<==、>、<、>=、<=字符串比较操作符=、==、!=、-n、-z,>、< 需要被转义=、==、!=、-n、-z,>、< 不需要被转义=、==、!=文件比较操作符-r、-l、-w、-x、-f、-d、-s、-nt、-ot-r、-l、-w、-x、-f、-d、-s、-nt、-ot不支持数学运算符+、-、*、/、%不支持+、-、*、/、%是否支持通配符匹配不支持支持不支持组合用各自逻辑符号连接的数字(运算)测试、文 件测试、字符测试