模块S05 条件表达式篇号S05-04 / 42预计阅读40 分钟主线Bash文章目录本篇目标30 秒速览正文1. 两种括号语句 vs 展开2. (( )) 作为条件3. 比较运算符整数4. 算术运算5. 自增自减 --6. 变量在 (( )) 里通常省略 $7. $(( )) 赋值与嵌套8. let老式写法9. 与 [、[[ 如何分工10. 易混写法对照11. 八进制与进制前缀12. 读脚本片段12.1 参数个数门禁12.2 重试计数12.3 与 test 退出码配合读脚本检查清单练习判断题实操题改错题S05 模块小结下一篇预告本篇目标掌握(( ... ))与$(( ... ))在条件里做整数比较、在脚本里做自增自减与简单算术。能读懂if (( $# 1 ))、(( i ))等写法知道与[的-eq、[[的分工并识别let的老式用法。30 秒速览(( expr ))算术语句表达式为真 → 退出码0可接if、。$(( expr ))算术展开结果替换进字符串如赋值、echo。里面写变量通常不加$(( n 0 ))、(( i ))。比较用!整数不是[的-eq。let与(( ))同类新脚本优先(( ))。运算是整数除法向零取整以0开头的常量可能被当八进制。正文1. 两种括号语句 vs 展开形式作用示例(( expr ))执行算术可作条件if (( n 1 )); then ...$(( expr ))算出数值嵌入命令行sum$(( a b ))a10b3echo$((ab))# 13((a))echo$a# 11if((ba));thenechob 小于 afi(( ))与$(( ))使用同一套算术规则前者侧重判断与副作用后者侧重取值。2.(( ))作为条件count5((count0))echo正数if((count5));thenecho等于 5fi表达式结果为非 0→ 条件为真→ 退出码0。结果为0→ 假 → 退出码1。不要用[的-eq写在((里# 错((count-eq5))# 对((count5))3. 比较运算符整数运算符含义!相等、不等小于、大于、小于等于、大于等于n10((n10))((n!0))((n20))((n10))参数个数读脚本极常见if(($#1));thenechousage:$0file2exit1fiif(($#2));thensecond$2fi$#在(( ))里可以写$#或#后者较少见带$更直观。4. 算术运算运算符含义-*/%加、减、乘、除、取模**幂Bash--自增、自减前缀/后缀x10((xx*21))# x 变为 21echo$((17%5))# 2echo$((2**10))# 1024除法为整数除法向零截断echo$((7/2))# 3echo$((-7/2))# -35. 自增自减--i0((i))# 后缀先取值再增整条式值为原值((i))# 前缀先增再取值j0((j2))# j j 2((j*3))循环里常见for((i0;i5;i));doecho$idonei0while((i5));doecho$i((i))donefor (( ... ))的语法在S07展开本篇先会认(( i ))即可。6. 变量在(( ))里通常省略$n10((n0))# 推荐(($n0))# 也可冗余namefoo# (( name foo )) # 错(( )) 做整数/算术不比字符串未定义变量在算术里视为0注意拼写错误不会报错((typo0))# typo 未定义 → 0条件为假set -u下未定义变量可能触发错误重要变量先赋值或${var:-0}。7.$(( ))赋值与嵌套base8offset2start$((baseoffset))len4end$((startlen))# 与参数展开配合S03-02sabcdefn2echo${s:$(( ${#s}- n ))}# 从右取 2 个字符ef8.let老式写法leti i 1leti1letnlet参数是算术表达式规则与(( ))相近。可读性不如(( i ))维护老脚本时会见到。# 等价letxx1((x))新脚本统一用(( ))/$(( ))。9. 与[、[[如何分工需求推荐整数比较、$#判断(( ))字符串相等、模式、正则[[ ]]S05-03文件存在、权限[[ -f ... ]]或[ -f ... ]S05-02POSIX /sh脚本[ $n -eq 10 ]S05-01# 常见组合if[[-f$f]](($(wc-l$f)100));thenecho大文件fi不要在[[里写(( count 10 ))这种「比较运算符」——会被当成重定向数值比较放进(( ))。10. 易混写法对照n10# 字符串感错用于比大小[$n10]# 字符串相等[[$n10]]# 整数比较[$n-eq10]# POSIX((n10))# Bash 算术# 算术结果放进字符串echoresult$((n*2))11. 八进制与进制前缀以0开头的常量可能被当作八进制((x09))# 可能报错09 不是合法八进制((x10))# 十进制 10从用户输入、文件读来的数字先当字符串处理必要时用10#${n}强制十进制进阶用法知道即可。12. 读脚本片段12.1 参数个数门禁(($#1))||{echousage:$0dir2;exit1;}12.2 重试计数max3try0while((trymax));doifrun_once;thenbreakfi((try))done12.3 与test退出码配合ifgrep-qerror$LOG(($(wc-l$LOG)0));thenalertfi读脚本检查清单数值比较是否用了(( ))而不是[[ $n 10 ]]在(( ))里是否误写了-eq-lt自增是(( i ))还是老式let i除法是否按整数理解未定义变量在算术里当0拼写错误会不会被掩盖练习判断题(( n 0 ))为真时退出码是 0。echo $(( 7 / 2 ))输出3.5。(( i ))与let i都能让i加 1。[[ $n -eq 10 ]]是判断整数 10 的推荐写法。if (( $# 1 )); then可用来检查是否缺少参数。参考答案对。错整数除法输出 3。对。错整数用(( n 10 ))或[ $n -eq 10 ]-eq在[[里不是常规写法。对。实操题运行并写出输出i0while((i3));doechoi$i((i))doneechofinal i$isum$((2**51))echosum$sum参考答案i0 i1 i2 final i3 sum33改错题n10if[[$n5]];thenechobigfiletn n 1if[$n-gt5];thenechostill bigfi参考n10if((n5));thenechobigfi((n))# 或: n$(( n 1 ))if((n5));thenechostill bigfi[[不做数值[ -gt可保留但需引号[ $n -gt 5 ]。S05 模块小结篇号工具典型用途S05-01[/testPOSIX 字符串、整数-eq、可移植S05-02[ -f -d ... ]文件、目录、权限S05-03[[ ]]模式 *.log、正则~、组合条件S05-04(( ))/$(( ))整数比较、$#、自增、算术展开下一模块S06把这些条件挂到控制流上if、elif、case。下一篇预告S06-01《if结构从单分支到elif嵌套》— 用本篇与 S05 的条件写出完整分支与else链。