要使Shell脚本程序具备一定的“智能”,面临的第一个问题就是如何区分不同的情况以确定执行何种操作。Shell环境根据命令执行后的返回状态值($?)来判断是否执行成功,当返回值为0时表示成功,否则(非0值)表示失败或异常。
使用专门的测试工具——test命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示条件成立)。
使用test测试命令时,有以下两种形式:
格式一: test 条件表达式
格式二: [ 条件表达式 ]
条件测试:判断某需求是否满足,需要由测试机制来实现,专用的测试表达式需要由测试命令辅助完成。
测试过程,实现评估布尔声明,以便用在条件性环境下进行执行:
- 若为真,则状态码变量 $? 返回0
-
若为假,则状态码变量 $? 返回非0
1 条件测试语句
1.1文件测试
格式一: test 操作符 表达式 格式二: [ 操作符 表达式 ] 常用的文件测试操作符:d | 测试文件是否为目录文件(Directory |
f | 测试文件是否为普通文件(File) |
e | 测试目录或文件是否存在(Exist)。建议使用-e,-a可能不准确。 |
a | 测试目录或文件是否存在(Exist) |
r | 测试当前用户是否有权限读取(Read) |
w | 测试当前用户是否有权限写入(Write) |
x | 测试当前用户是否有权限执行(eXcute) |
L | 测试是否为符号链接(软链接文件) |
nt | 判断文件A是否比文件B新 |
ot | 判断文件A是否比文件B旧 |
ef | 判断两个文件是否为同一文件。可用于硬链接,主要判断两个文件是否指向同一个inode |
-s FILE | 判断文件是否存在且非空 |
-t fd | fd 指定文件描述符是否在某终端已经打开 |
-N FILE | 文件自从上一次被读取之后是否被修改过 |
-O FILE | 当前有效用户是否为文件属主 |
-G FILE | 当前有效用户是否为文件属组 |
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030154702903-711722461.png)
示例2:
-e和-a都可以测试文件是否存在,但和 !(取反)连用时,-a可能不准确,建议使用-e。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030154726469-220271381.png)
示例3:
测试root用户对文件是否拥有读、写、执行权限。
发现root用户的读取和写入权限,不受文件的基本权限控制;但执行权限受文件基本权限控制。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030154750940-1038580384.png)
示例4:
测试软链接时,目录名称后面不要加"/",不然会被判断为目录文件。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030154846274-1177428889.png)
1.2 整数测试
整数值比较:
[ 整数变量1 操作符 整数变量2 ]
test 整数变量1 操作符 整数变量2
操作符:
-eq | 等于(Equal) |
-ne | 不等于(Not Equal) |
-gt | 大于(Greater Than) |
-lt | 小于(Lesser Than) |
-le | 小于或等于(Lesser or Equal |
-ge | 大于或等于(Greater or Equal |
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030155649258-45036393.png)
示例2:
查询当前目录下的文件数量是否大于10,如果大于,则进行提示。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030155722141-70534649.png)
1.3 字符串测试
常用的测试操作符
- =:字符串内容相同
- !=:字符串内容不同,! 号表示相反的意思
- -z:字符串内容为空
- -n:字符是否存在
字符串比较,常用的四种格式
[ "字符串1" = "字符串2" ] //测试字符串1和字符串2的内容是否相同 [ "字符串1" != "字符串2” ] //测试字符串1和字符串2的内容是否不同 [ -z "字符串" ] //测试字符串是否为空,或者指定的变量是否为空值。(测试字符串的长度是否为零) [ -n "字符串" ] //测试字符串是否存在,即是否不为空。(测试字符串的长度是否非零) 示例1:![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030155854294-569106964.png)
示例2:
使用-z或-n测试变量时,变量需要加引号,避免有歧义而导致判断结果有误。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030155921909-1848058667.png)
1.4 逻辑测试(短路运算)
逻辑测试用于连接多个测试条件,并返回整个表达式的值。 逻辑测试主要有"逻辑与","逻辑或","逻辑否"三种。
逻辑测试两种格式:
格式一:[ 表达式1 ] 逻辑运算符 [ 表达式2 ] ... #例:[表达式1] && [表达式2] 等同于 [表达式1 -a 表达式2] 等同于 [[表达式1 && 表达式2]] #例:[表达式1] || [表达式2] 等同于 [表达式1 -o 表达式2] 等同于 [[表达式1 || 表达式2]] 格式二:命令1 逻辑运算符 命令2 ...逻辑运算符:
- -a或&& :逻辑与,“而且”的意思,全真才为真。
- -o或|| :逻辑或,“或者”的意思,一真即为真。
- ! :逻辑否。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160054001-908233572.png)
1)短路与 &&
CMD1 && CMD2 全真才为真,一假即为假。 第一个CMD1结果为真 ,第二个CMD2必须要参与运算,才能得到最终的结果。 第一个CMD1结果为假 ,总的结果必定为假,因此不需要执行CMD2。 同时满足命令1 和命令2 的要求,才会返回正确。 2)短路或 ||CMD1 || CMD2 一真即为真 第一个CMD1结果为真,总的结果必定为真,因此不需要执行CMD2。 第一个CMD1结果为假,第二个CMD2必须要参与运算,才能得到最终的结果。
1.4.1 二元运算符
示例1:
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160219095-892030282.png)
示例2:
[表达式1] && [表达式2]
等同于 [表达式1 -a 表达式2]
等同于 [[表达式1 && 表达式2]]
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160246560-1511965545.png)
2 if 语句
2.1 if 单分支结构
单分支语句格式: if 判断条件 then 条件成立的分支代码 fi![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160458705-1268820878.png)
案例应用:
判断已用磁盘空间是否大于80%,如果是就报警提示。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160612408-1208155768.png)
测试脚本:
可以先将判断条件修改为大于20%,测试脚本是否生效。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160656045-934126888.png)
2.2 if 双分支结构
双分支语句格式
if 判断条件
then 条件成立的分支代码
else 条件不成立的分支代码
fi
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160835095-1642873218.png)
案例应用:
检测80端口是否在监听,如果是,则提示”网站服务已在运行“;如果否,则启动httpd服务。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030160907916-1291263021.png)
2.3 if 多分支结构
多分支语句格式:
if 判断条件1 then 条件1为真的分支代码 elif 判断条件2 then 条件2为真的分支代码 elif 判断条件3 then 条件3为真的分支代码 ... else 以上条件都为假的分支代码 fi案例应用:
查看当前时间点,根据不同时间范围输出不同问候语。
- 6点-10点,输出早上好;
- 11点-13点,输出中午好;
- 14点-18点,输出下午好;
- 19点-22点, 输出晚上好;
- 其他时间,休息时间。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030161107982-2111964036.png)
3 case语句
v格式:case 变量引用in 模式1) 命令分支1 ;; 模式2) 命令分支2 ;; ... *) 默认命令分支 esac 注意事项: case支持glob风格的通配符: * :任意长度任意字符 ? :任意单个字符 [0-9] :指定范围内的任意单个字符 | :“或者”的意思,如: a|b
案例应用:
提示用户输入分数(0-100),判断分数范围,分出优秀、良好、及格、不及格四档。如果用户输入的分数值不在0-100之间,则提示重新输入。
![](/i/l/?n=22&i=blog/2964616/202210/2964616-20221030161416493-1229220831.png)
4 易错总结
- 测试文件是否存在时,建议使用-e。如:[ -e /etc/passwd ]
- root用户的读取和写入权限,不受文件的基本权限控制;但执行权限受文件基本权限控制。
- 测试软链接时,目录名称后面不要加"/",不然会被判断为目录文件。如:[ -L /bin ]
- 使用-z或-n测试变量时,变量需要加引号,避免有歧义而导致判断结果有误。如:[ -n "$empty" ]
标签:语句,case,shell,文件,是否,示例,测试,字符串,表达式 From: https://www.cnblogs.com/jct166289/p/16841534.html