news 2026/9/17 8:11:18

精通 Bash 条件表达式(Conditional Expressions):文件、字符串、算术与退出状态检测全指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
精通 Bash 条件表达式(Conditional Expressions):文件、字符串、算术与退出状态检测全指南

精通 Bash 条件表达式(Conditional Expressions):文件、字符串、算术与退出状态检测全指南

【免费下载链接】introduction-to-bash-scriptingFree Introduction to Bash Scripting eBook项目地址: https://gitcode.com/GitHub_Trending/in/introduction-to-bash-scripting

Bash 条件表达式是编写一切可靠脚本的基石:无论是判断文件是否存在、比较字符串与数字,还是检查上一条命令是否成功,都离不开[[ ]][ ]这两组命令。本文基于开源电子书《Introduction to Bash Scripting》中 法语版第 9 章 与 英文版第 9 章 的内容,系统梳理 Bash 中最常用的条件表达式清单,并补充变量展开、引号、通配符匹配等实战陷阱,帮助你读完即可在脚本中直接套用。

在计算机科学中,条件语句(conditional statements)、条件表达式(conditional expressions)与条件构造(conditional constructs)是编程语言的核心特性:它们根据开发者指定的布尔条件(truefalse)执行不同的计算或动作。在 Bash 中,条件表达式由[[复合命令(compound command)与[内建命令(built-in command)提供,用于测试文件属性以及执行字符串比较与算术比较

一、理解[[[的区别

在深入表达式清单之前,先明确两处使用前提:

  • [[ ... ]]是 Bash 的复合命令(compound command),是关键字而非普通命令,支持模式匹配、逻辑运算符&&/||、以及==/!=两侧的 glob 通配符展开,是 Bash 脚本中的首选写法;
  • [ ... ]是等效于test内建命令,属于 POSIX 标准写法,可移植性更强,但它对变量值中的空格敏感(要求严格引号),也不支持模式匹配。

正如英文原版章节所指出的:当与[[一起使用时,==会执行模式匹配;若要完全符合 POSIX 规范,则应使用=配合test/[命令。

二、文件表达式(File Expressions):检测文件与目录属性

文件表达式用于测试某个路径是否存在、类型以及权限属性。以下是最常用的清单,直接复制即可使用(${fichier}为存放路径的变量):

表达式含义
[[ -a ${fichier} ]]文件存在即真
[[ -b ${fichier} ]]文件存在且为块特殊文件(block special file,如磁盘设备)
[[ -c ${fichier} ]]文件存在且为字符特殊文件(character special file,如终端设备)
[[ -d ${fichier} ]]文件存在且为目录
[[ -e ${fichier} ]]文件存在即真(-a的历史别名)
[[ -f ${fichier} ]]文件存在且为普通文件
[[ -h ${fichier} ]]文件存在且为符号链接(同-L
[[ -r ${fichier} ]]文件存在且可读
[[ -s ${fichier} ]]文件存在且大小大于 0
[[ -w ${fichier} ]]文件存在且可写
[[ -x ${fichier} ]]文件存在且可执行
[[ -L ${fichier} ]]文件存在且为符号链接(同-h

典型场景:脚本启动时校验配置文件是否存在、目录是否可写、可执行文件是否有执行权限。例如:

#!/bin/bash config="/etc/myapp/config.ini" if [[ ! -f "${config}" ]]; then echo "配置文件不存在: ${config}" exit 1 fi

注意!可对整个表达式取反([[ ! -d ${dir} ]]表示"目录不存在"),这是条件表达式在实战中最常用的变形之一。

三、字符串表达式(String Expressions):判空、判等与排序比较

字符串表达式用于检测变量是否已赋值、字符串长度是否为零,以及字符串之间的相等与字典序关系:

表达式含义
[[ -v ${varname} ]]变量varname已被赋值(存在)
[[ -z ${string} ]]字符串长度为 0
[[ -n ${string} ]]字符串长度不为 0
[[ ${string1} == ${string2} ]]字符串相等
[[ ${string1} != ${string2} ]]字符串不相等
[[ ${string1} < ${string2} ]]string1在字母序上先于string2
[[ ${string1} > ${string2} ]]string1在字母序上后于string2

这里有三个高频踩坑点,值得单独说明:

  1. -v接收的是变量名而非值:英文原版章节特别标注——-v操作符期望传入变量名(varname),如果错误地传入${varname}(展开后的值),表达式将恒为假。正确写法是[[ -v varname ]]
  2. ==右侧默认是 glob 模式:在[[ ]]中,==!=的右侧除非被引号包裹,否则会被当作通配符模式处理。例如[[ $name == *.log ]]会匹配所有以.log结尾的字符串。如果你要的是精确字符串比较,务必给右侧加引号[[ ${string1} == "${string2}" ]]。这个规则同样适用于!=
  3. <>需要转义:在[ ](test 命令)中使用\<\>,因为裸的</>会被 shell 当作重定向符;在[[ ]]中则无需转义,如清单所示。

-z判空是本书后续条件语句章节中最常用的表达式——用户输入校验几乎都从它开始。

四、算术运算符(Arithmetic Operators):整数比较

当需要比较两个整数(可为正数或负数)时,使用以下运算符,切勿与字符串的=/==混淆:

表达式含义
[[ ${arg1} -eq ${arg2} ]]arg1等于arg2
[[ ${arg1} -ne ${arg2} ]]arg1不等于arg2
[[ ${arg1} -lt ${arg2} ]]arg1小于arg2
[[ ${arg1} -le ${arg2} ]]arg1小于或等于arg2
[[ ${arg1} -gt ${arg2} ]]arg1大于arg2
[[ ${arg1} -ge ${arg2} ]]arg1大于或等于arg2

需要留意的是,这些运算符只适用于整数(包括负整数),不能直接用于浮点数比较;浮点数比较需要借助bcawk等外部工具。另外,在[[ ]]的算术比较中,变量可以省略$前缀(如[[ num -gt 10 ]]),但为保持清晰一致,本书示例统一使用${arg1}形式。

五、组合条件:AND 与 OR

与其他编程语言一样,Bash 支持用逻辑运算符组合多个测试条件:

[[ test_case_1 ]] && [[ test_case_2 ]] # 逻辑与(AND):两者皆真才为真 [[ test_case_1 ]] || [[ test_case_2 ]] # 逻辑或(OR):任一为真即为真

注意这里的&&||位于两个[[ ]]之间,它们同时也是 shell 层面的命令连接符,具有短路求值语义:&&左侧为假时右侧不再执行,||左侧为真时右侧不再执行。这一特性在后续章节的 if 示例中被大量使用,例如同时校验"用户名不是 admin"与"当前用户不是 root"的多条件防护逻辑。

六、退出状态运算符(Exit Status Operators):检查命令成败

每个 Bash 命令执行后都会返回一个退出状态码(exit status),存放在特殊变量$?中:0表示成功,非零表示出错。可以用算术运算符把它包装成条件表达式:

[[ $? -eq 0 ]] # 上一条命令成功且无错误时返回真 [[ $? -gt 0 ]] # 上一条命令失败或出错时返回真

更惯用的写法是直接利用命令本身的退出状态作为 if 条件(if command; then ...),因为if天然接受命令的退出码;[[ $? -eq 0 ]]这种显式写法更适合在需要把状态码"翻译"成条件表达式的场景中使用。注意$?非常"易失"——任何一条中间命令(包括赋值、echo)都会覆盖它的值,因此应尽快消费。

七、从表达式到条件构造:在脚本中实际使用

本章是纯"表达式清单",而它们真正的用武之地在下一章《Bash 条件语句》中,那里会用ifif-elseelifcase将这些表达式组装成完整逻辑。一个最小示例提前预览其用法:

#!/bin/bash read -p "Quel est votre nom ? " nom if [[ -z ${nom} ]]; then echo "Veuillez entrer votre nom !" else echo "Salut ${nom}" fi

[[ -z ${nom} ]]正是本章的字符串判空表达式:当用户输入为空时进入提示分支,否则进入问候分支。本书章节的编排顺序(变量 → 用户输入 → 数组 → 条件表达式 → 条件语句 → 循环 → 函数)也印证了这一点:条件表达式是承接输入处理、通向流程控制的关键一环。

八、仓库中的质量保障:shellcheck 验证每个代码块

值得一提的工程实践是,本仓库提供了 scripts/shellcheck-ebook.sh:它会自动抽取英文版电子书所有 markdown 文件中的bash代码块,逐个写入临时文件并运行 shellcheck 进行静态检查,退出码0表示全部通过、1表示存在告警。脚本还通过EXCLUDE变量豁免了若干"教学场景故意为之"的告警码,例如:

  • SC2034/SC2154:变量看似未使用或未赋值(片段中定义的变量供后续片段使用);
  • SC2078test_case_1这类占位符导致的常量表达式;
  • SC2043/SC2211:刻意演示的反例代码块与 crontab 语法行。

这意味着你在本书中学到的每一个表达式写法,都经过 shellcheck 以 warning 级别以上的严格度校验,可以直接放心复制到自己的脚本中。整个电子书本身通过 Ibis 工具链(PHP 编写的 Markdown 电子书生成器)构建,并已产出 PDF 与 EPUB 成品(见 ebook/en/export 目录)。

九、小结与建议

条件表达式是 Bash 脚本判断力的来源,建议按以下方式巩固:

  1. 把本文的文件、字符串、算术三张清单当作速查表,需要时回来查阅,无需死记硬背(原书也如此建议);
  2. 牢记三个易错点:-v传变量名、==右侧加引号做精确比较、-z/-n配合用户输入校验;
  3. 继续阅读《Bash 条件语句》学习if/elif/case的组合用法,并参考本书英文原版章节获取更多补充说明(如-v与模式匹配的注意事项)。

掌握这些表达式后,你将能够写出对文件、用户输入、数值与命令结果做出正确分支判断的健壮脚本,这也是迈向自动化 SysOps/DevOps 任务的第一步。

【免费下载链接】introduction-to-bash-scriptingFree Introduction to Bash Scripting eBook项目地址: https://gitcode.com/GitHub_Trending/in/introduction-to-bash-scripting

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 8:10:22

Oracle AS OF TIMESTAMP 原理与实战:从快照查询到数据治理

1. 项目概述&#xff1a;为什么“AS OF TIMESTAMP”不是救命稻草&#xff0c;而是手术刀在Oracle数据库运维现场&#xff0c;我见过太多次这样的场景&#xff1a;开发同事凌晨两点发来消息&#xff0c;“刚误删了生产库的用户表&#xff0c;数据全没了&#xff0c;能不能救&…

作者头像 李华
网站建设 2026/9/17 8:08:10

Python YAML模块在接口测试中的高效应用与安全实践

1. Python YAML 模块在接口测试中的核心价值在2026年的现代接口测试实践中&#xff0c;YAML已经成为配置管理的首选格式。相比其他数据格式&#xff0c;YAML具有几个不可替代的优势&#xff1a;人类可读性&#xff1a;采用缩进和自然语言风格&#xff0c;比JSON更接近日常文档注…

作者头像 李华
网站建设 2026/9/17 8:08:08

DC/DC电源仿真:非理想建模、环路稳定性与瞬态预测实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/17 8:08:08

脾脏转染不再难:SPguide一键式体内电转方案详解

做免疫研究的人&#xff0c;几乎没有谁没被脾脏“折磨”过。脾脏这个器官很特别&#xff0c;它是成年小鼠体内最大的次级淋巴器官&#xff0c;T细胞、B细胞、树突状细胞、巨噬细胞全堆在里面&#xff0c;可以说你想要的免疫细胞类型它都有&#xff0c;几乎任何免疫应答都能在脾…

作者头像 李华
网站建设 2026/9/17 8:07:05

Android音乐播放器项目实战:MediaPlayer与Service核心机制解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华