Shell脚本编写之分支结构与循环结构Linux Shell 分支、循环、函数Python 对照版1. 关系运算符对比1.1 整数与逻辑运算对照表1.2 文件测试运算符Shell 独有优势2. if 分支结构2.1 语法结构对照2.2 ⚠️ 关键差异速查3. case 多分支结构3.1 语法结构对照3.2 ⚠️ 关键差异速查3.3 高级模式匹配示例4. while 循环结构4.1 语法结构对照4.2 逐行读取文件经典场景对照4.3 ⚠️ 关键差异速查5. for 循环结构5.1 语法结构对照5.2 数值范围循环对照5.3 ⚠️ 关键差异速查6. 函数定义与参数传递6.1 语法结构对照6.2 参数传递对照6.3 返回值与作用域对照6.4 ⚠️ 关键差异速查6.5 实用技巧与最佳实践Linux Shell 分支、循环、函数Python 对照版课前必读核心思维转换Python是通用编程语言注重数据结构与对象抽象。Shell是系统低级语言本质是命令行操作的脚本化封装。⚠️切记Shell 不是“简化版 Python”不要将 Python 的语法习惯如缩进、赋值空格、符号比较直接套用到 Shell 中1. 关系运算符对比1.1 整数与逻辑运算对照表功能Python 写法Shell[ ]写法字母表示数值比较运算符表示字符串比较Shell(( ))写法(只能用于比较数值)⚠️ Shell 避坑指南等于a b[ $a -eq $b ](( a b ))-eq(equal);[ ]中字符串用数字必须用-eq不等于a ! b[ $a -ne $b ](( a ! b ))-ne(not equal);数字比较必须用-ne大于a b[ $a -gt $b ](( a b ))-gt(greater than);[ ]中是字符串比较数字比较必须用-gt小于a b[ $a -lt $b ](( a b ))-lt(less than);[ ]中字符串比较数字比较必须用-lt字符串比较大于等于a b[ $a -ge $b ](( a b ))-ge(greater than or equal); 数字比较必须用-geshell中没有字符串大于等于的比较运算符小于等于a b[ $a -le $b ](( a b ))-le(less than or equal); 数字比较必须用-leshell中没有字符串小于等于的比较运算逻辑与and[ A ] [ B ](( A B ))Shell 无and关键字课本的-a已过时避免使用逻辑或or[ A ] || [ B ](( A || B ))Shell 无or关键字 课本-o已过时避免使用逻辑非not! [ A ](( !A ))⚠️注意[ condition ]condition两侧必须有空格()两侧可无空格且()内部可以不使用$符号1.2 文件测试运算符Shell 独有优势Python 对比Python 需import os调用os.path.exists()等函数Shell内置文件测试无需导入任何模块。Shell 运算符功能说明Python 等价写法-f file普通文件存在os.path.isfile(file)-d file目录存在os.path.isdir(file)-e file文件/目录存在os.path.exists(file)-r / -w / -x可读 / 可写 / 可执行os.access(file, os.R_OK)2. if 分支结构2.1 语法结构对照# Pythonscoreint(input(成绩: ))ifscore90:print(A)elifscore80:print(B)else:print(C)# Shellread-p成绩: scoreif[$score-ge90];thenechoAelif[$score-ge80];thenechoBelseechoCfi2.2 ⚠️ 关键差异速查对比项PythonShell学生高频错误代码块界定强制缩进then ... fi关键字以为缩进有效漏写fi条件格式if condition:if [ condition ]; then漏写[ ]或分号;变量安全自动处理 None必须加双引号$var空值导致[ ]参数缺失报错赋值语法x 10(有空格)x10(无空格)写成x 10被解析为执行命令结束标记无必须fi闭合嵌套 if 时忘记闭合–3. case 多分支结构3.1 语法结构对照# Python使用 if-elif-else 模拟 casefruitinput(请输入水果: )iffruitapple:print(这是苹果)eliffruitbanana:print(这是香蕉)eliffruitorange:print(这是橙子)else:print(未知水果)# Shell使用 case 语句read-p请输入水果: fruitcase$fruitinapple)echo这是苹果;;banana)echo这是香蕉;;orange)echo这是橙子;;*)echo未知水果;;esac3.2 ⚠️ 关键差异速查对比项PythonShell学生高频错误多分支语法if-elif-elsecase ... in ... esac忘记写;;或esac模式匹配精确匹配支持通配符*、?、[ ]模式字符串要加引号默认分支else:*)忘记写*)默认分支结束标记无必须esac闭合漏写esac分支结束符无必须;;结束漏写;;导致语法错误3.3 高级模式匹配示例# Shell case 支持通配符read-p请输入文件名: filenamecase$filenamein*.txt)echo文本文件;;*.jpg|*.png|*.gif)echo图片文件;;script-*.sh)echo脚本文件;;[0-9]*)echo以数字开头的文件;;*)echo其他类型文件;;esac4. while 循环结构4.1 语法结构对照# Pythoncount0whilecount5:print(count)count1# Shellcount0while[$count-lt5];doecho$countcount$((count1))# ⚠️ 算术自增必须用 $(( ))done4.2 逐行读取文件经典场景对照# Pythonwhileopen(data.txt)asf:forlineinf:print(line.strip())# Shell输入重定向喂数据whileIFSread-rline;doecho$linedonedata.txt4.3 ⚠️ 关键差异速查对比项PythonShell说明自增运算count 1count$((count 1))Shell 不支持对变量直接文件读取for line in fwhile read重定向Shell 用重定向将文件作为标准输入无限循环while True:while true; doShell 的true是系统命令非布尔值跳出控制break/continuebreak/continue✅ 完全一致无缝迁移5. for 循环结构5.1 语法结构对照# Pythonnames[alice,bob,charlie]fornameinnames:print(fHello,{name})# Shell空格分隔无方括号无逗号namesalice bob charliefornamein$names;doechoHello,$namedone5.2 数值范围循环对照# Pythonforiinrange(1,6):# 输出 1,2,3,4,5不含右端点print(i)# Shell 方式1花括号展开推荐foriin{1..5};do# 输出 1,2,3,4,5包含右端点echo$idone# Shell 方式2C 风格最接近传统编程for((i1;i5;i));doecho$idone5.3 ⚠️ 关键差异速查对比项PythonShell注意列表表示[a, b, c]方括号逗号a b c纯空格分隔Shell 无列表字面量语法范围边界range()左闭右开{1..5}左闭右闭边界差 1 是最常见 bug代码块缩进do ... done漏写done是最常见错误变量引用name/f{name}$name/${name}Shell 取值必须加$命令输出作列表subprocess.run()$(command)Shell 天然支持如 for f in $(ls *6. 函数定义与参数传递6.1 语法结构对照# Pythondefgreet(name,times1):向指定用户问好指定次数foriinrange(times):print(fHello,{name}!)# 调用函数greet(Alice,3)greet(Bob)# 使用默认参数# Shellgreet(){# 函数定义function_name() { ... }localname$1# 第一个位置参数localtimes${2:-1}# 第二个参数默认值为1for((i0;itimes;i));doechoHello,$name!done}# 调用函数greetAlice3greetBob# 使用默认参数6.2 参数传递对照# Python 参数传递defprocess_data(name,age,*args,**kwargs):print(fName:{name}, Age:{age})print(fExtra args:{args})print(fKeyword args:{kwargs})process_data(Alice,25,extra1,extra2,cityBeijing,jobEngineer)# Shell 参数传递process_data(){# 位置参数localname$1# $1 第一个参数localage$2# $2 第二个参数echoName:$name, Age:$age# 额外参数从 $3 开始shift2# 移除前两个参数echoExtra args:$# ⚠️ Shell 不支持关键字参数但可以通过特殊约定模拟# 例如--keyvalue 格式}process_dataAlice25extra1extra26.3 返回值与作用域对照# Pythondefcalculate_sum(a,b):resultab# 局部变量returnresult totalcalculate_sum(10,20)print(fSum:{total})# Shellcalculate_sum(){locala$1# 使用 local 声明局部变量localb$2localresult$((ab))# Shell 函数通过 echo 返回值echo$result# 或使用 return 返回状态码0-255return0}# 获取函数输出total$(calculate_sum1020)echoSum:$total# 获取函数退出状态calculate_sum1020status$?echoExit status:$status6.4 ⚠️ 关键差异速查对比项PythonShell学生高频错误函数定义def func():func() { ... }漏写()或{ }参数访问arg1, arg2$1, $2, $, $#忘记$符号引用参数默认参数def func(argdefault)${2:-default}参数展开使用复杂默认值逻辑错误返回值return valueecho value$()捕获误用return返回数据只能返回状态码变量作用域默认局部默认全局需local声明局部忘记local导致变量污染可变参数*args$所有参数混淆$和$*的区别参数个数len(args)$#忘记检查参数个数导致错误函数调用func(arg1, arg2)func arg1 arg2添加括号或逗号分隔参数6.5 实用技巧与最佳实践# Shell 函数最佳实践示例# 1. 参数验证validate_input(){if[$#-lt2];thenechoUsage:$0name age2return1filocalname$1localage$2# 参数类型检查if![[$age~^[0-9]$]];thenechoError: Age must be a number2return1fiechoValid input:$name,$agereturn0}# 2. 返回复杂数据使用全局变量或文件get_system_info(){local-Ainfo# 关联数组Bash 4.0info[hostname]$(hostname)info[kernel]$(uname-r)info[memory]$(free-h|awk/^Mem:/ {print $2})# 通过 declare -p 输出数组定义declare-pinfo}# 调用并解析返回的数组eval$(get_system_info)echoHostname:${info[hostname]}echoKernel:${info[kernel]}