shell脚本中的各种表达式介绍和使用

简介:

shell脚本中的各种表达式介绍和使用
阅读目录

1.条件测试表达式
2.文件表达式
3.字符串表达式
4.整数表达式
5.逻辑操作符

前言:在shell脚本中,有各种的表达式,包括有条件测试表达式,文件表达式,字符串表达式,整数表达式,接下来我们来了解一下他们的使用方法

1.条件测试表达式

首先来看一下条件测试语法

条件测试语法 #说明

1.test <测试表达式> test命令和后面<内容>之间至少有一个空格
2.[ <测试表达式> ] 单中括号进行条件测试表达式,[]的边界和内容之间至少要有一个空格
3.[[ <测试表达式> ]] 双括号,[[]]的边界和内容也是要有空格
4.((<测试表达式>)) 双小括号,两端不用空格

注意点

1、语法1中的test命令和语法2中的[]是等价的。语法3中的[[]]为扩展的test命令,语法4中的(())常用于计算

2、在[[]](双中括号)中可以使用通配符等进行模式匹配,这是其区别其他集中语法格式的地方

3、&&、||、>、<等操作符可以应用于[[]]中,但不能应用于[]中,在[]中一般用-a、-o、-gt(用于整数)、-lt(用于整数)代替上述操作符

4、对于整数的关系运算,也可以使用shell的算术运算符(())

详解

1.1.test条件测试的语法和使用

查看帮助:man test

介绍:test - check file types and compare values(检查文件类型和比较值)

语法格式: test <测试表达式>

test的帮助文档

[root@shell ~]# man test > 1.txt

[root@shell ~]# cat 1.txt

 View Code

使用

例一:判断如果file文件存在且为一个文件,就输出true,否则输出false

[root@shell ~]# test -f file && echo true || echo false
false

讲解:因为file这个文件不存在,所以输出false,&&是并且的意思,||表示前面一个执行失败才会执行后面

例二:使用-z选项(如果测试字符串的长度为0,则表达式成立)

[root@shell ~]# test -z "guoke" && echo 1 || echo 0
0  #因为测试的字符串为guoke,不为空值,所以为假输出0
[root@shell ~]# char="guoke"
[root@shell ~]# test -z "$char" && echo 1 || echo 0
0  #因为guoke赋值给了char,所以也不是空值,输出0
[root@shell ~]# char=""
[root@shell ~]# test -z "$char" && echo 1 || echo 0
1  #char为空值,所以长度为0,表达式成立输出1

1.2.[]中括号条件测试语法和使用

语法格式:[ <测试表达式> ]

注意点:中括号内部的两端都要有空格,[]和test用法一样,test的判断选项也可以在[]中用

输入两端都有空格的技巧:先输入一对中括号,然后退一个格,输入两个空格,再退一个格

例子:利用[]加-f选项(如果文件存在且为普通文件则表达式就成立)

[root@shell ~]# [ -f /tmp/guoke.txt ] && echo 1 || echo 0
0  #文件不存在所以输出0
[root@shell ~]# touch /tmp/guoke.txt
[root@shell ~]# [ -f /tmp/guoke.txt ] && echo 1 || echo 0
1  #文件存在且为一个普通文件,则输出1
[root@shell ~]# [ -f /tmp/guoke.txt ] && echo 1
1

1.3.[[]] 双中括号条件测试语法及使用

语法格式:[[ <测试表达式> ]]

注意点:双中括号的两端需要有空格

例子:判断文件存在且为一个普通文件

[root@shell ~]# [[ -f /tmp/test.txt ]] && echo 1 || echo 0
0  #文件不存在所以条件不成立,输出0
[root@shell ~]# touch /tmp/test.txt
[root@shell ~]# [[ -f /tmp/test.txt ]] && echo 1 || echo 0
1  #文件存在且为普通文件,条件成立,输出1
[root@shell ~]# [[ -f /tmp/test.txt ]] && echo 1
1

1.4.特殊条件测试表达式例子

判断条件测试表达式的条件成立或不成立后,还需要执行多条命令语句的语法,不用if测试表达式的格式

当条件1成立时,同时执行多条命令

test 条件1 && {

}

[ 条件1 ] && {

命令1
命令2  

}
[[ 条件1 ]] && {

}

例子:当条件成立的时候就执行后面的命令

[root@shell ~]# cat test.sh

!/bin/bash

[ $1 -eq 3 ] && {

echo 1
echo 2
echo 3

}

[root@shell ~]# sh test.sh 3 #传参
1
2
3

上面的判断相当于下面if语句的效果

if [ 条件1 ];then

命令1
命令2

fi

关于条件测试表达式的总结

1.test和[]、[[]]的功能有所重合,因此在工作中选择一种适合自己的一种用,其他的可以看懂别人的写的脚本就好了,可以同man test查看更多参数用法

2.测试表达式test、[]、[[]]、(())区别总结

测试表达式符号    test    [] [[]]    (())
边界是否需要空格    需要    需要 需要    不需要
逻辑操作符    !、-a、-o    !、-a、-o   !、&&、|| !、&&、||
整数比较操作符      -eq -gt -lt -ge -le(test,[],[[]])    = < > >= <=
字符串比较操作符        =、==、!= (全部支持)
是否支持通配符匹配     不支持    不支持 支持 不支持

2.文件表达式

常用的文件测试操作符

常用操作符 #说明

-f 文件,全称file #文件存在且为普通文件则为真,表达式成立
-d 文件,全称directory #文件存在且为目录则为真,表达式成立
-s 文件,全称size #文件存在且大小不为0为真
-e 文件,全称exist #文件存在则为真
-r 文件,全称read #文件存在且为可读则为真,表达式成立
-w 文件,全称write #文件存在且可写为真,表达式成立
-x 文件,全称executable #文件存在且可执行为真
-L 文件,全称link #文件存在且为链接文件为真
f1 -nt f2,英文newer than #文件f1比文件f2新则为真,根据文件修改时间计算
f1 -ot f2,英文older than #文件f1比文件f2旧为真,根据修改时间计算

提示:这些操作符对于test,[],[[]]几乎是通用的,可以使用man test查看更多的操作符

例子:

1.-f,判断文件是否存在且为普通文件

[root@shell ~]# touch test
[root@shell ~]# ls -l test
-rw-r--r-- 1 root root 0 Mar 18 16:02 test
[root@shell ~]# [ -f test ] && echo 1 || echo 0
1 #解析:因为文件存在且为普通文件,所以为真输出1

2.-d,判断文件是否存在且为目录

[root@shell ~]# mkdir test1
[root@shell ~]# [ -d test1 ] && echo 1 || echo 0
1 #因为文件存在且为目录,所以为真输出1,如果不存在就输出0

3.测试文件属性:r,w,x

[root@shell ~]# ls -ld test
-rw-r--r-- 1 root root 0 Mar 18 16:02 test
[root@shell ~]# [ -r test ] && echo 1 || echo 0
1 #文件存在且可读,为真,输出1
[root@shell ~]# [ -w test ] && echo 1 || echo 0
1 #文件存在且可写,为真,输出1
[root@shell ~]# [ -x test ] && echo 1 || echo 0
0  #文件不可执行,不为真,所以输出0
[root@shell ~]# chmod +x test
[root@shell ~]# [ -x test ] && echo 1 || echo 0
1 #加了可执行权限就为真成立了

提示:测试文件的读、写、执行等属性,不光是根据文件属性rwx的标识来判断,还要看当前执行测试的用户是否真的可以按照对应的权限操作该文件

测试时变量的特殊写法及问题

用[]测试变量时,如果被测试的变量不加双引号,那么测试结果可能会是不正确的

例子

[root@shell ~]# echo $test #不存在的变量

[root@shell ~]# [ -f $test ] && echo 1 || echo 0 #不加引号返回的结果时错误的
1
[root@shell ~]# [ -f "$test" ] && echo 1 || echo 0 #添加以后返回的结果是正确的
0

注意点:做测试判断时,不一定非要按照前面的如果成立了输出什么,不成立输出什么,可以直接做部分判断

[root@shell ~]# [ -x test ] && echo 1 #如果test文件可执行,就输出1,否则不做任何输出
[root@shell ~]# [ -f /etc ] || echo 0 #如果前面执行失败就输出0,否则不做任何输出
0

3.字符串表达式

字符串表达式作用:比较两个字符串是否相同、测试字符串的长度是否为0、字符串是否为null等

常用的字符串测试操作符

常用字符串操作符 #说明

-z "字符串" 如果字符串长度为0则为真,
-n "字符串" 如果字符串长度不为0则为真,
"字符串1" = "字符串2" 如果字符串1等于字符串2则为真,可以使用==代替=
"字符串1" != "字符串2" 如果字符串1不等于字符串2则为真,不能使用!==代替!=

提示:

1.上面的字符串测试操作符必须要有""引起来

2.比较符号两端要有空格

3.-n 比较字符串长度是否不为0,如果不为0则为真,用法 [ -n "$my" ]

4.-z 比较字符串长度是否为0,如果为0则为真,用法 [ -z "$my" ]

例1:-n,-z参数应用

[root@shell ~]# [ -n "abc" ] && echo 1 || echo 0
1 #-n是不为空则为真,字符串长度为abc,所以长度不是为0,为真输出1
[root@shell ~]# test -n "aa" && echo 1 || echo 0
1
[root@shell ~]# test -n "" && echo 1 || echo 0
0 #字符串为空,不为真,数以输出0
[root@shell ~]# var="test"
[root@shell ~]# [ -n "$var" ] && echo 1|| echo 0
1
[root@shell ~]# [ -z "$var" ] && echo 1|| echo 0
0 #-z是为空值为真,不为空值为假,所以输出0,
[root@shell ~]# [ "aa" = "aa" ] && echo 1 || echo 0
1 #字符串相等,所以长度为0,为真

例二:进行字符串比较时,如果等号两端没有空格带来的问题

[root@shell ~]# [ "abc"="1" ]&& echo 1 || echo 0
1 #等号两边没有空格,明显是不成立的也输出了1
[root@shell ~]# [ "abc" = "1" ]&& echo 1 || echo 0
0 #正常现象

总结:字符串比较时若等号两端没有空格,则会导致判断出现逻辑错误,即使语句没有问题,但是结果依然可能不对

例三:字符串不加引号可能带来的问题

[root@shell ~]# var="" #将变量内容设置为空
[root@shell ~]# [ -n "$var" ] && echo 1 || echo 0
0 #-n是值不为空则为真,因为变量内容为0,为空值,所以不为真,输出0
[root@shell ~]# [ -n $var ] && echo 1 || echo 0
1 #不加双引号导致返回结果错误
[root@shell ~]# [ -z "$var" ]&& echo 1 || echo 0
1 #-z是字符串长度为0,则为真

查看有关双引号和等号两端空格的生产系统标准

[root@shell ~]# sed -n '30,31p' /etc/init.d/network

Check that networking is up.

[ "${NETWORKING}" = "no" ] && exit 6

4.整数表达式

整数二元比较操作符

在test及[]中使用的比较符号 在[[]]和(())中使用的比较符号 说明
-eq == 或 = 相等,全称equal
-ne != 不相等,全称not qeual
-gt > 大于,全称greater than
-ge >= 大于等于,全称为greater equal
-lt < 小于,全称less than
-le <= 小于等于,全称less equal

提示:如果选择整数比较的时候,要确保两边是整数,如[ 2 -eq 1 ]

注意:"<"和">"在[]中括号里面需要转义,对于数字不转义的结果可能不会报错,但是结果可能不对,=和!=在[]不用转义

例子

[root@shell ~]# [ 2 > 3 ] && echo 1 || echo 0
1 #结果应该返回0,但是不转义返回了1是错误的
[root@shell ~]# [ 2 > 3 ] && echo 1 || echo 0
0 #进行转义之后输出正确
[root@shell ~]# [ 2 < 1 ] && echo 1 || echo 0
1
[root@shell ~]# [ 2 < 1 ] && echo 1 || echo 0
0

整数比较的推荐用法,使用-eq,-lt,-gt

例子

[root@shell ~]# [ 13 -lt 24 ] && echo 1
1 #13小于24结果为真就输出1

5.逻辑操作符

常用的逻辑操作符

在test及[]中使用的比较符号 在[[]]和(())中使用的比较符号 说明

-a                              &&                     and,且,两端都为真,则结果为真
-o                              ||                     or,或,两端有一个为真,则结果为真
 !                               !                     not,非,两端相反,则结果为真

提示

1、逻辑操作符前后的表达式是否成立,一般用真假来表示
2、“!”的中文意思是反,即与一个逻辑值相反的逻辑值
3、-a的中文意思是“与”(and或&&),前后两个逻辑值都为“真”,综合返回值才为真,否则为假
4、-o的中文意思是“或”(or或||),前后两个逻辑值只要有一个为真,返回值就为真
5、连接两行[]、test或[[]]的表达式可用&&或||

提示:中括号里面不能使用&&字符串,否则报错,在[[]]和(())里面就可以用,可参考上面列出的

[root@shell ~]# [ -f "$f1" && -f "$f2" ] && echo 1 || echo 0
-bash: [: missing `]'
0

例一:

[root@shell ~]# f1=/etc/rc.local
[root@shell ~]# f2=/etc/services
[root@shell ~]# [ -f "$f1" -a -f "$f2" ] && echo 1 || echo 0
1  #判断如果f2和f2变量的文件存在且为文件的话,就为真,输出1,如果一个不为真,那么久不为真,就输出0
[root@shell ~]# [[ -f "$f1" && -f "$f2" ]] && echo 1 || echo 0
1  #在[[]]双中括号中就可以使用&&
[root@shell ~]# [ -f "$f1" ]&&[ -f "$f2" ] && echo 1 || echo 0
1  #或者在两个[]之间使用&&也可以

例二:

[root@shell ~]# a=1
[root@shell ~]# b=2
[root@shell ~]# [ "$a" -eq 2 -a "$b" -eq 2 ] && echo 1 || echo 0
0 #如果变量a等于2且变量b也等于2,则为真,否则为假,输出0
[root@shell ~]# [ "$a" -eq 1 -a "$b" -eq 2 ] && echo 1 || echo 0
1
[root@shell ~]# [ "$a" -eq 1 -o "$b" -eq 2 ] && echo 1 || echo 0
1 #如果变量a等于或变量b等于2,则为真,输出1,-o是或,有一个条件成立则为真
[root@shell ~]# [ "$a" -eq 2 -o "$b" -eq 3 ] && echo 1 || echo 0
0

原文地址https://www.cnblogs.com/guoke-boy/p/12516071.html

相关文章
|
9月前
|
存储 安全 Unix
七、Linux Shell 与脚本基础
别再一遍遍地敲重复的命令了,把它们写进Shell脚本,就能一键搞定。脚本本质上就是个存着一堆命令的文本文件,但要让它“活”起来,有几个关键点:文件开头最好用#!/usr/bin/env bash来指定解释器,并用chmod +x给它执行权限。执行时也有讲究:./script.sh是在一个新“房间”(子Shell)里跑,不影响你;而source script.sh是在当前“房间”里跑,适合用来加载环境变量和配置文件。
841 9
|
关系型数据库 MySQL Shell
MySQL 备份 Shell 脚本:支持远程同步与阿里云 OSS 备份
一款自动化 MySQL 备份 Shell 脚本,支持本地存储、远程服务器同步(SSH+rsync)、阿里云 OSS 备份,并自动清理过期备份。适用于数据库管理员和开发者,帮助确保数据安全。
|
9月前
|
存储 Shell Linux
八、Linux Shell 脚本:变量与字符串
Shell脚本里的变量就像一个个贴着标签的“箱子”。装东西(赋值)时,=两边千万不能有空格。用单引号''装进去的东西会原封不动,用双引号""则会让里面的$变量先“变身”再装箱。默认箱子只能在当前“房间”(Shell进程)用,想让隔壁房间(子进程)也能看到,就得给箱子盖个export的“出口”戳。此外,Shell还自带了$?(上条命令的成绩单)和$1(别人递进来的第一个包裹)等许多特殊箱子,非常有用。
868 2
|
Shell
Shell脚本循环控制:shift、continue、break、exit指令
使用这些命令可以让你的Shell脚本像有生命一样动起来。正确使用它们,你的脚本就能像一场精心编排的舞蹈剧目,既有旋律的起伏,也有节奏的跳跃,最终以一场惊艳的表演结束。每一个动作、每一个转折点,都准确、优雅地完成所需要表达的逻辑。如此,你的脚本不只是冰冷的代码,它透过终端的界面,跳着有节奏的舞蹈,走进观众——使用者的心中。
404 60
|
Shell
一个用于添加/删除定时任务的shell脚本
一个用于添加/删除定时任务的shell脚本
457 1
|
9月前
|
数据采集 监控 Shell
无需Python:Shell脚本如何成为你的自动化爬虫引擎?
Shell脚本利用curl/wget发起请求,结合文本处理工具构建轻量级爬虫,支持并行加速、定时任务、增量抓取及分布式部署。通过随机UA、异常重试等优化提升稳定性,适用于日志监控、价格追踪等场景。相比Python,具备启动快、资源占用低的优势,适合嵌入式或老旧服务器环境,复杂任务可结合Python实现混合编程。
|
11月前
|
Web App开发 缓存 安全
Linux一键清理系统垃圾:释放30GB空间的Shell脚本实战​
这篇博客介绍了一个实用的Linux系统盘清理脚本,主要功能包括: 安全权限检查和旧内核清理,保留当前使用内核 7天以上日志文件清理和系统日志压缩 浏览器缓存(Chrome/Firefox)、APT缓存、临时文件清理 智能清理Snap旧版本和Docker无用数据 提供磁盘空间使用前后对比和大文件查找功能 脚本采用交互式设计确保安全性,适合定期维护开发环境、服务器和个人电脑。文章详细解析了脚本的关键功能代码,并给出了使用建议。完整脚本已开源,用户可根据需求自定义调整清理策略。
1246 1
|
存储 Unix Shell
确定Shell脚本在操作系统中的具体位置方法。
这对于掌握Linux的文件系统组织结构和路径方面的理解很有帮助,是我们日常工作和学习中都可能使用到的知识。以上讲解详细清晰,应用简便,是每一个想要精通操作系统的计算机爱好者必备的实用技能。
682 17
|
Linux Shell
在Linux、CentOS7中设置shell脚本开机自启动服务
以上就是在CentOS 7中设置shell脚本开机自启动服务的全部步骤。希望这个指南能帮助你更好地管理你的Linux系统。
2171 25
|
Linux Shell
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
Centos或Linux编写一键式Shell脚本删除用户、组指导手册
399 4