2026/2/16 1:43:16
网站建设
项目流程
厦门城乡建设厅网站,网站原则,ps怎么艺术字字体设计网站,广州做鞋的网站完整bash语法教程#xff1a;从零到专家
第一部分#xff1a;bash基础概念
1. 什么是bash#xff1f;
#!/bin/bash
# 这是bash脚本的第一行#xff0c;称为shebang#xff0c;指定解释器
# bash是Unix/Linux系统的命令行解释器#xff0c;也是脚本语言# 执行方式1从零到专家第一部分bash基础概念1. 什么是bash#!/bin/bash# 这是bash脚本的第一行称为shebang指定解释器# bash是Unix/Linux系统的命令行解释器也是脚本语言# 执行方式1直接执行需要执行权限# chmod x script.sh# ./script.sh# 执行方式2使用bash解释器不需要执行权限# bash script.sh# 执行方式3source命令在当前shell执行# source script.sh 或 . script.sh2. 基本语法结构#!/bin/bash# 第一个bash脚本echoHello, bash!# echo命令输出文本echo当前目录:$(pwd)# $(command)执行命令并获取输出echo用户:$USER# 输出结果# Hello, bash!# 当前目录: /home/user# 用户: username第二部分变量和数据类型1. 变量定义和使用#!/bin/bash# 1. 定义变量等号前后不能有空格nameAliceage25salary5000.50# 2. 使用变量echo姓名:$name# 使用$前缀echo年龄:${age}# 使用{}明确变量边界echo薪水:$salary# 3. 只读变量readonlycountryChina# countryUSA # 取消注释会报错readonly variable# 4. 删除变量unsetsalaryecho薪水:$salary# 输出空值# 5. 变量类型declare-iint_var10# 整数变量declare-rconst100# 只读变量declare-llowerHELLO# 自动转为小写declare-uupperhello# 自动转为大写echo整数:$int_varecho小写:$lower# 输出: helloecho大写:$upper# 输出: HELLO# 输出结果# 姓名: Alice# 年龄: 25# 薪水: 5000.50# 薪水:# 整数: 10# 小写: hello# 大写: HELLO2. 特殊变量#!/bin/bash# 运行脚本: bash special_vars.sh arg1 arg2 arg 3echo脚本名:$0# 脚本名称echo参数个数:$## 参数数量echo所有参数:$*# 所有参数作为一个字符串echo所有参数列表:$# 所有参数的列表echo第一个参数:$1# 第一个参数echo第二个参数:$2# 第二个参数echo第三个参数:$3# 第三个参数echo进程ID:$$# 当前脚本进程IDecho退出状态:$?# 上一条命令的退出状态echo后台进程:$!# 最后一个后台进程ID# 测试命令执行状态ls/tmp/dev/nullechols命令状态:$?# 0表示成功ls/nonexistent2/dev/nullecho错误命令状态:$?# 非0表示失败# 输出结果# 脚本名: special_vars.sh# 参数个数: 3# 所有参数: arg1 arg2 arg 3# 所有参数列表: arg1 arg2 arg 3# 第一个参数: arg1# 第二个参数: arg2# 第三个参数: arg 3# 进程ID: 12345# 退出状态: 0# 后台进程:# ls命令状态: 0# 错误命令状态: 23. 数组操作#!/bin/bash# 1. 定义数组fruits(applebananaorangegrape)# 2. 访问数组元素echo第一个水果:${fruits[0]}# 索引从0开始echo所有水果:${fruits[]}# 所有元素echo水果个数:${#fruits[]}# 数组长度# 3. 遍历数组echo遍历数组:forfruitin${fruits[]};doecho -$fruitdone# 4. 修改数组fruits[1]mango# 修改元素fruits(peach)# 添加元素echo修改后的数组:${fruits[]}# 5. 关联数组bash 4.0declare-A person person[name]Bobperson[age]30person[city]New Yorkecho关联数组:forkeyin${!person[]};do# 获取所有键echo$key:${person[$key]}done# 6. 删除数组元素unsetfruits[2]echo删除后:${fruits[]}# 输出结果# 第一个水果: apple# 所有水果: apple banana orange grape# 水果个数: 4# 遍历数组:# - apple# - banana# - orange# - grape# 修改后的数组: apple mango orange grape peach# 关联数组:# name: Bob# age: 30# city: New York# 删除后: apple mango grape peach第三部分字符串操作1. 字符串基础#!/bin/bashstr1Hellostr2World# 1. 字符串拼接greeting$str1,$str2!echo拼接:$greeting# Hello, World!# 2. 字符串长度echo长度:${#greeting}# 13# 3. 字符串提取echo提取1-5:${greeting:0:5}# Helloecho提取7-end:${greeting:7}# World!# 4. 字符串查找和替换textI love apples, apples are tastyecho原始:$textecho替换第一个:${text/apples/oranges}# I love oranges, apples are tastyecho替换全部:${text//apples/oranges}# I love oranges, oranges are tastyecho替换前缀:${text/#I love/He likes}# He likes apples, apples are tastyecho替换后缀:${text/%tasty/delicious}# I love apples, apples are delicious# 5. 大小写转换mixedHello Worldecho大写:${mixed^^}# HELLO WORLDecho小写:${mixed,,}# hello worldecho首字母大写:${mixed^}# Hello World# 6. 删除子串path/usr/local/bin/script.shecho原始路径:$pathecho删除最短前缀:${path#*/}# usr/local/bin/script.shecho删除最长前缀:${path##*/}# script.shecho删除最短后缀:${path%/*}# /usr/local/binecho删除最长后缀:${path%%/*}# (空)# 7. 默认值unsetmaybe_emptyecho默认值:${maybe_empty:-默认文本}# 默认文本echo变量值:${maybe_empty}# (空)maybe_empty有值echo默认值:${maybe_empty:-默认文本}# 有值# 输出结果# 拼接: Hello, World!# 长度: 13# 提取1-5: Hello# 提取7-end: World!# 原始: I love apples, apples are tasty# 替换第一个: I love oranges, apples are tasty# 替换全部: I love oranges, oranges are tasty# 替换前缀: He likes apples, apples are tasty# 替换后缀: I love apples, apples are delicious# 大写: HELLO WORLD# 小写: hello world# 首字母大写: Hello World# 原始路径: /usr/local/bin/script.sh# 删除最短前缀: usr/local/bin/script.sh# 删除最长前缀: script.sh# 删除最短后缀: /usr/local/bin# 删除最长后缀:# 默认值: 默认文本# 变量值:# 默认值: 有值第四部分运算符1. 算术运算符#!/bin/basha10b3# 1. 使用 $(( ))echo加法:$((ab))# 13echo减法:$((a-b))# 7echo乘法:$((a*b))# 30echo除法:$((a/b))# 3 (整数除法)echo取余:$((a%b))# 1echo指数:$((a**b))# 1000# 2. 使用 letletc a becholet结果:$c# 13# 3. 使用 expr (旧方法)d$(expr$a $b)echoexpr结果:$d# 13# 4. 浮点数运算 (使用bc)e$(echoscale2;$a/$b|bc)echo浮点除法:$e# 3.33# 5. 自增自减((a))echo自增后:$a# 11((b--))echo自减后:$b# 2# 6. 位运算x5# 0101y3# 0011echo与运算:$((xy))# 1 (0001)echo或运算:$((x|y))# 7 (0111)echo异或:$((x^y))# 6 (0110)echo左移:$((x1))# 10 (1010)echo右移:$((x1))# 2 (0010)# 输出结果# 加法: 13# 减法: 7# 乘法: 30# 除法: 3# 取余: 1# 指数: 1000# let结果: 13# expr结果: 13# 浮点除法: 3.33# 自增后: 11# 自减后: 2# 与运算: 1# 或运算: 7# 异或: 6# 左移: 10# 右移: 22. 关系运算符#!/bin/bashx10y20z10# 数值比较echo数值比较:echox y:$((xy))# 0 (假)echox y:$((xy))# 1 (真)echox z:$((xz))# 1echox z:$((xz))# 1echox z:$((xz))# 1echox ! y:$((x!y))# 1# 字符串比较str1hellostr2worldstr3helloecho-e\n字符串比较:if[[$str1$str3]];thenechostr1等于str3# 输出fiif[[$str1!$str2]];thenechostr1不等于str2# 输出fiif[[-z]];thenecho空字符串# 输出fiif[[-n$str1]];thenecho非空字符串# 输出fi# 输出结果# 数值比较:# x y: 0# x y: 1# x z: 1# x z: 1# x z: 1# x ! y: 1## 字符串比较:# str1等于str3# str1不等于str2# 空字符串# 非空字符串3. 逻辑运算符#!/bin/basha10b20# 逻辑运算if[[$a-lt15$b-gt15]];thenechoa15 且 b15# 输出fiif[[$a-gt15||$b-gt15]];thenechoa15 或 b15# 输出fiif[[!$a-gt15]];thenechoa不大于15# 输出fi# 短路运算[[-f/etc/passwd]]echo文件存在# 输出[[-f/nonexistent]]||echo文件不存在# 输出# 输出结果# a15 且 b15# a15 或 b15# a不大于15# 文件存在# 文件不存在第五部分控制结构1. 条件判断#!/bin/bash# 1. if-elif-elsenum75if[[$num-ge90]];thenecho优秀elif[[$num-ge80]];thenecho良好elif[[$num-ge70]];thenecho中等# 输出elif[[$num-ge60]];thenecho及格elseecho不及格fi# 2. case语句fruitapplecase$fruitinapple)echo这是苹果# 输出;;banana)echo这是香蕉;;orange|lemon)echo这是柑橘类;;*)echo未知水果;;esac# 3. 测试命令 test 和 [ ]file/etc/passwdiftest-f$file;thenecho文件存在(使用test)# 输出fiif[-f$file];thenecho文件存在(使用[ ])# 输出fiif[[-f$file-r$file]];thenecho文件存在且可读# 输出fi# 输出结果# 中等# 这是苹果# 文件存在(使用test)# 文件存在(使用[ ])# 文件存在且可读2. 循环结构#!/bin/bash# 1. for循环echofor循环示例:# 方式1遍历列表foriin12345;doecho数字:$idone# 方式2遍历命令输出forfilein$(ls/tmp|head-3);doecho文件:$filedone# 方式3C语言风格for((i1;i3;i));doecho计数:$idone# 2. while循环echo-e\nwhile循环示例:count1while[[$count-le3]];doechowhile:$count((count))done# 3. until循环echo-e\nuntil循环示例:num1until[[$num-gt3]];doechountil:$num((num))done# 4. 无限循环echo-e\n无限循环(按CtrlC停止):# while true; do# echo 循环中...# sleep 1# done# 5. 循环控制echo-e\n循环控制:foriin{1..10};doif[[$i-eq3]];thencontinue# 跳过本次循环fiif[[$i-eq8]];thenbreak# 跳出循环fiecho处理:$idone# 输出结果# for循环示例:# 数字: 1# 数字: 2# 数字: 3# 数字: 4# 数字: 5# 文件: file1# 文件: file2# 文件: file3# 计数: 1# 计数: 2# 计数: 3## while循环示例:# while: 1# while: 2# while: 3## until循环示例:# until: 1# until: 2# until: 3## 循环控制:# 处理: 1# 处理: 2# 处理: 4# 处理: 5# 处理: 6# 处理: 7第六部分函数1. 函数基础#!/bin/bash# 1. 函数定义say_hello(){localname$1# local定义局部变量echoHello,$name!return0# 返回状态码(0-255)}# 2. 调用函数say_helloAlice# 传递参数echo返回值:$?# 获取返回值# 3. 带返回值的函数add(){localsum$(($1$2))echo$sum# 通过echo返回值(可以返回字符串)}result$(add1020)echo加法结果:$result# 4. 参数处理process_args(){echo参数个数:$#echo所有参数:$echo第一个参数:$1echo第二个参数:$2# 遍历所有参数forargin$;doecho参数:$argdone}process_argsarg1arg2arg3# 5. 递归函数factorial(){localn$1if[[$n-le1]];thenecho1elselocalprev$(factorial$((n-1)))echo$((n*prev))fi}echo5的阶乘:$(factorial5)# 输出结果# Hello, Alice!# 返回值: 0# 加法结果: 30# 参数个数: 3# 所有参数: arg1 arg2 arg3# 第一个参数: arg1# 第二个参数: arg2# 参数: arg1# 参数: arg2# 参数: arg3# 5的阶乘: 120第七部分输入输出1. 标准输入输出#!/bin/bash# 1. 读取用户输入echo-n请输入您的名字: readusernameecho你好,$username!# 2. 读取多个值echo-n请输入姓名和年龄: readname ageecho姓名:$name, 年龄:$age# 3. 静默读取(用于密码)echo-n请输入密码: read-s passwordecho-e\n密码已接收# 4. 超时设置echo-n请在5秒内输入: read-t5timeout_input||echo时间到!echo输入:$timeout_input# 5. 读取文件行echo读取/etc/passwd前3行:count0whileIFSread-r line[[$count-lt3]];doecho行$((count1)):$line((count))done/etc/passwd# 6. 重定向echo重定向示例:echo这是标准输出output.txt# 覆盖写入echo这是追加内容output.txt# 追加写入catoutput.txt# 错误重定向ls/nonexistent2error.log# 错误输出到文件ls/tmpall_output.log# 所有输出到文件# 7. 管道echo-e\n管道示例:echo-eapple\nbanana\ncherry\napple|sort|uniq-c# 8. Here DocumentcatEOF 这是Here Document 可以输入多行文本 直到遇到结束标记EOF EOF# 输出结果# 请输入您的名字: Alice# 你好, Alice!# 请输入姓名和年龄: Bob 25# 姓名: Bob, 年龄: 25# 请输入密码:# 密码已接收# 请在5秒内输入: hello# 输入: hello# 读取/etc/passwd前3行:# 行 1: root:x:0:0:root:/root:/bin/bash# 行 2: daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin# 行 3: bin:x:2:2:bin:/bin:/usr/sbin/nologin# 重定向示例:# 这是标准输出# 这是追加内容## 管道示例:# 2 apple# 1 banana# 1 cherry# 这是Here Document# 可以输入多行文本# 直到遇到结束标记EOF第八部分高级特性1. 进程和作业控制#!/bin/bash# 1. 后台运行echo启动后台进程:sleep5bg_pid$!echo后台进程PID:$bg_pid# 2. 等待进程echo等待后台进程完成...wait$bg_pidecho后台进程完成# 3. 作业控制echo-e\n作业控制:sleep3sleep2jobs# 显示作业列表fg%1# 将作业1调到前台jobs# 再次显示# 4. 信号处理trapecho 收到SIGINT信号; exit 1SIGINTecho按CtrlC测试信号处理# sleep 10 # 取消注释测试# 5. 子shellecho-e\n子shell示例:(echo子shell中cd/tmppwd# 输出: /tmp)pwd# 输出原始目录# 输出结果# 启动后台进程:# 后台进程PID: 12345# 等待后台进程完成...# 后台进程完成## 作业控制:# [1]- 运行中 sleep 3 # [2] 运行中 sleep 2 ## 按CtrlC测试信号处理## 子shell示例:# 子shell中# /tmp# /home/user2. 调试和错误处理#!/bin/bash# 1. 调试模式set-x# 开启调试显示执行的命令echo调试模式开始debug_vartestecho变量值:$debug_varsetx# 关闭调试echo调试模式结束# 2. 错误处理选项set-e# 遇到错误立即退出set-u# 使用未定义变量时报错set-o pipefail# 管道中任一命令失败则整个管道失败# 3. 自定义错误处理error_handler(){echo错误发生在第$1行echo命令:$2echo退出码:$3}traperror_handler${LINENO}$BASH_COMMAND$?ERR# 测试错误ls/nonexistent# 这会产生错误# 4. 脚本选项处理whilegetopts:a:b:copt;docase$optina)echo选项-a的值:$OPTARG;;b)echo选项-b的值:$OPTARG;;c)echo选项-c被设置;;\?)echo无效选项: -$OPTARG;;:)echo选项-$OPTARG需要参数;;esacdone# 运行: bash script.sh -a value1 -b value2 -c# 输出结果# echo 调试模式开始# 调试模式开始# debug_vartest# echo 变量值: test# 变量值: test# set x# 调试模式结束# 错误发生在第 27 行# 命令: ls /nonexistent# 退出码: 2# 选项-a的值: value1# 选项-b的值: value2# 选项-c被设置第九部分实战示例1. 系统监控脚本#!/bin/bash# 系统监控脚本# 颜色定义RED\033[0;31mGREEN\033[0;32mYELLOW\033[1;33mNC\033[0m# No Color# 获取系统信息get_system_info(){echo-e${GREEN} 系统信息 ${NC}# 主机信息echo-e${YELLOW}主机名:${NC}$(hostname)echo-e${YELLOW}系统版本:${NC}$(cat/etc/os-release|grepPRETTY_NAME|cut-d-f2)echo-e${YELLOW}内核版本:${NC}$(uname-r)echo-e${YELLOW}运行时间:${NC}$(uptime-p|seds/up //)# CPU信息localload$(uptime|awk-Fload average:{print$2})echo-e${YELLOW}负载:${NC}$load# 内存信息localmem_total$(free-h|awk/Mem:/ {print$2})localmem_used$(free-h|awk/Mem:/ {print$3})localmem_percent$(free|awk/Mem:/ {printf %.1f,$3/$2*100})echo-e${YELLOW}内存使用:${NC}$mem_used/$mem_total($mem_percent%)# 磁盘信息localdisk_usage$(df-h /|awkNR2 {print$5})echo-e${YELLOW}根分区使用:${NC}$disk_usage# 进程信息localprocess_count$(psaux|wc-l)echo-e${YELLOW}进程数:${NC}$((process_count-1))# 用户信息localuser_count$(who|wc-l)echo-e${YELLOW}登录用户:${NC}$user_count}# 检查服务状态check_service(){localservice$1ifsystemctl is-active --quiet$service;thenecho-e$service:${GREEN}运行中${NC}elseecho-e$service:${RED}停止${NC}fi}# 检查端口check_port(){localport$1ifnetstat-tuln|grep:$port/dev/null;thenecho-e 端口$port:${GREEN}监听中${NC}elseecho-e 端口$port:${RED}未监听${NC}fi}# 主函数main(){get_system_infoecho-e\n${GREEN} 服务状态 ${NC}check_servicesshdcheck_servicenginxcheck_servicemysqlecho-e\n${GREEN} 端口状态 ${NC}check_port22check_port80check_port3306# 告警检查echo-e\n${GREEN} 告警检查 ${NC}# 内存检查localmem_percent$(free|awk/Mem:/ {printf %.0f,$3/$2*100})if[[$mem_percent-gt90]];thenecho-e${RED}警告: 内存使用率超过90%!${NC}elif[[$mem_percent-gt80]];thenecho-e${YELLOW}注意: 内存使用率超过80%${NC}elseecho-e${GREEN}内存使用正常${NC}fi# 磁盘检查localdisk_percent$(df/|awkNR2 {print$5}|tr-d%)if[[$disk_percent-gt90]];thenecho-e${RED}警告: 磁盘使用率超过90%!${NC}elif[[$disk_percent-gt80]];thenecho-e${YELLOW}注意: 磁盘使用率超过80%${NC}elseecho-e${GREEN}磁盘使用正常${NC}fi}# 运行主函数main2. 备份脚本#!/bin/bash# 文件备份脚本CONFIG_FILEbackup.confLOG_FILEbackup.log# 读取配置文件if[[-f$CONFIG_FILE]];thensource$CONFIG_FILEelse# 默认配置BACKUP_DIR./backupsSOURCE_DIRS(./etc)RETENTION_DAYS7COMPRESStruefi# 创建备份目录mkdir-p$BACKUP_DIR# 日志函数log_message(){locallevel$1localmessage$2localtimestamp$(date%Y-%m-%d %H:%M:%S)echo[$timestamp] [$level]$message|tee-a$LOG_FILE}# 错误处理handle_error(){log_messageERROR备份失败:$1exit1}# 执行备份perform_backup(){localbackup_namebackup_$(date%Y%m%d_%H%M%S)localbackup_path$BACKUP_DIR/$backup_namelog_messageINFO开始备份:$backup_name# 创建临时目录mkdir-p$backup_path||handle_error无法创建备份目录# 备份每个目录fordirin${SOURCE_DIRS[]};doif[[-d$dir]];thenlog_messageINFO备份目录:$dirlocaldir_name$(basename$dir)if[[$dir_name.]];thendir_namecurrentficp-r$dir$backup_path/$dir_name||\log_messageWARNING无法备份$direlselog_messageWARNING目录不存在:$dirfidone# 压缩备份if[[$COMPRESStrue]];thenlog_messageINFO压缩备份文件...tar-czf$backup_path.tar.gz-C$BACKUP_DIR$backup_name||\handle_error压缩失败# 删除未压缩的目录rm-rf$backup_pathbackup_path$backup_path.tar.gzfilog_messageINFO备份完成:$(du-h$backup_path|cut-f1)echo$backup_path}# 清理旧备份cleanup_old_backups(){log_messageINFO清理$RETENTION_DAYS天前的备份...localdeleted_count0forbackupin$BACKUP_DIR/backup_*;doif[[-f$backup]]||[[-d$backup]];thenlocalbackup_age$((($(date%s)-$(stat-c%Y $backup))/86400))if[[$backup_age-gt$RETENTION_DAYS]];thenlog_messageINFO删除旧备份:$(basename$backup)(${backup_age}天)rm-rf$backup((deleted_count))fifidonelog_messageINFO清理完成删除了$deleted_count个旧备份}# 主函数main(){log_messageINFO 备份脚本开始 # 检查源目录localvalid_dirs0fordirin${SOURCE_DIRS[]};doif[[-d$dir]];then((valid_dirs))fidoneif[[$valid_dirs-eq0]];thenhandle_error没有有效的源目录fi# 执行备份backup_file$(perform_backup)# 清理旧备份cleanup_old_backups# 生成报告localtotal_size$(du-sh$BACKUP_DIR|cut-f1)localbackup_count$(ls-1$BACKUP_DIR/backup_*2/dev/null|wc-l)log_messageINFO备份统计:log_messageINFO 备份目录:$BACKUP_DIRlog_messageINFO 总大小:$total_sizelog_messageINFO 备份数量:$backup_countlog_messageINFO 最新备份:$(basename$backup_file)log_messageINFO 备份脚本结束 # 发送通知可选# send_notification 备份完成: $(basename $backup_file)}# 运行主函数main$第十部分最佳实践总结1. 安全实践#!/bin/bash# bash最佳实践示例# 1. 使用set命令增强安全性set-euo pipefail# 启用严格模式set-o nounset# 使用未定义变量时报错set-o errexit# 命令失败时退出set-o pipefail# 管道失败时退出# 2. 总是引用变量path/path with spaces# 错误: ls $path# 正确:ls$path# 3. 使用[[ ]]代替[ ]进行测试if[[-f$file-r$file]];then# 更安全功能更强大fi# 4. 使用函数提高可重用性log(){locallevel$1localmessage$2echo[$(date)] [$level]$message}# 5. 使用local定义局部变量calculate(){localresult$(($1$2))echo$result}# 6. 验证输入validate_input(){if[[-z$1]];thenecho错误: 参数不能为空exit1fiif[[!$1~ ^[a-zA-Z]$]];thenecho错误: 只允许字母exit1fi}# 7. 使用trap清理资源cleanup(){rm-f$TEMP_FILEecho清理完成}trapcleanup EXIT# 8. 提供使用帮助usage(){catEOF 用法:$0[选项] 参数 选项: -h, --help 显示帮助信息 -v, --version 显示版本信息 -d, --debug 启用调试模式 示例:$0--debug test EOF}# 9. 使用getopts处理参数whilegetopts:hvd:opt;docase$optinh)usage;exit0;;v)echo版本 1.0.0;exit0;;d)DEBUG$OPTARG;;\?)echo无效选项: -$OPTARG2;exit1;;:)echo选项 -$OPTARG需要参数2;exit1;;esacdone# 10. 添加脚本头信息: 脚本名称: best_practice.sh 作者: Your Name 版本: 1.0.0 描述: bash最佳实践示例 创建日期: 2024-01-01 修改历史: 2024-01-01: 创建脚本 # 11. 使用颜色和格式输出RED\033[0;31mGREEN\033[0;32mYELLOW\033[1;33mNC\033[0mecho-e${GREEN}成功消息${NC}echo-e${RED}错误消息${NC}echo-e${YELLOW}警告消息${NC}2. 性能优化#!/bin/bash# 性能优化示例# 1. 避免不必要的子shell# 不好:result$(echo$var|tra-zA-Z)# 好:result${var^^}# 2. 使用内置字符串操作代替外部命令# 不好:length$(echo$str|wc-c)# 好:length${#str}# 3. 批量处理而不是循环处理# 不好:forfilein*.txt;domv$file${file%.txt}.bakdone# 好:rename.txt.bak*.txt# 4. 使用数组代替多个变量# 不好:item1value1item2value2item3value3# 好:items(value1value2value3)# 5. 使用here string代替echo管道# 不好:echo$data|greppattern# 好:greppattern$data# 6. 缓存命令输出# 不好: 多次执行相同命令if[[$(who|wc-l)-gt5]];thenecho用户数:$(who|wc-l)fi# 好: 缓存结果user_count$(who|wc-l)if[[$user_count-gt5]];thenecho用户数:$user_countfi# 7. 使用算术展开代替expr# 不好:result$(expr$a $b)# 好:result$((ab))# 8. 提前退出减少嵌套# 不好:if[[-f$file]];thenif[[-r$file]];then# 处理文件fifi# 好:[[-f$file]]||exit1[[-r$file]]||exit1# 处理文件# 9. 使用函数减少重复代码process_file(){localfile$1[[-f$file]]||return1# 处理逻辑}# 10. 并行处理process_items(){localitem$1# 处理单个项目}# 顺序处理# for item in ${items[]}; do# process_items $item# done# 并行处理(如果有大量数据)foritemin${items[]};doprocess_items$itemdonewait通过这个完整教程你已经掌握了bash从基础到高级的所有概念。记住实践是最好的老师- 多写脚本解决实际问题阅读优秀代码- 学习开源项目的bash脚本掌握调试技巧- 使用set -x、echo调试关注安全性- 避免常见的安全漏洞保持代码简洁- 复杂的逻辑考虑用其他语言实现祝你成为bash专家