Shell编程精髓:表达式与数组实战指南
一、表达式基础:逻辑与测试
1. 测试表达式基础
# 测试表达式两种写法 test 1 == 1 # 传统写法 [ 1 == 1 ] # 常用写法(注意空格)# 检查命令执行状态 echo $? # 0表示成功,1表示失败
2. 逻辑表达式实战
# && 逻辑与(全部成功才执行) [ $# -eq 1 ] && echo "参数数量正确"# || 逻辑或(一个失败就执行) [ $# -ne 1 ] || echo "参数数量错误"# ! 逻辑非(取反) [ ! -f file.txt ] && echo "文件不存在"# 组合使用 [ -d /etc ] && echo "目录存在" || echo "目录不存在"
二、高级表达式应用
1. 字符串表达式
# 内容比较 [ $user == "root" ] # 相等判断 [ $pass != "123" ] # 不等判断# 空值判断 [ -z "$var" ] # 空值返回真 [ -n "$var" ] # 非空返回真
2. 文件表达式
# 属性判断 [ -f file.txt ] # 普通文件 [ -d /tmp ] # 目录文件 [ -L link ] # 符号链接# 权限判断 [ -r file ] # 可读 [ -x script.sh ] # 可执行# 存在判断 [ -e path ] # 存在 [ -s file ] # 存在且非空
3. 数字表达式
# 数值比较 [ 10 -gt 5 ] # 大于 [ 3 -eq 3 ] # 等于 [ 4 -le 5 ] # 小于等于
4. 条件组合技巧
# 使用-a/-o组合 [ $age -gt 18 -a $age -lt 60 ] # 与关系 [ -f file -o -d dir ] # 或关系# 使用&&/||组合 [[ $user == "admin" && $pass == "secret" ]] [[ -r file || -w file ]]
三、数组操作全解析
1. 数组定义与操作
# 定义数组 files=(*.sh) # 文件列表 colors=("red" "green" "blue") # 字符串数组 mixed=([0]=123 [2]="text") # 混合数组(稀疏)# 获取元素 echo ${files[0]} # 第一个元素 echo ${colors[@]} # 所有元素 echo ${!mixed[@]} # 所有索引# 数组长度 echo ${#colors[@]} # 元素数量 echo ${#colors[0]} # 第一个元素长度
2. 数组修改与删除
# 修改元素 colors[1]="yellow" # 修改第二个元素 files[0]=${files[0]/.sh/.bak} # 修改扩展名# 删除元素 unset files[2] # 删除第三个元素 unset colors # 删除整个数组
3. 关联数组(键值对)
# 声明和使用关联数组 declare -A user_info user_info=([name]="John" [age]=30 [role]="admin")echo ${user_info[name]} # 输出 John echo ${!user_info[@]} # 输出键名:name age role
四、实战案例解析
1. CPU负载统计脚本
#!/bin/bash # 获取CPU负载信息 cpu_load=($(uptime | tr -s " " | cut -d " " -f 9-11 | tr "," " "))# 彩色输出结果 echo -e "\e[31m\t系统CPU负载信息\e[0m" echo -e "\e[32m=================================" echo "CPU 1 min平均负载: ${cpu_load[0]}" echo "CPU 5 min平均负载: ${cpu_load[1]}" echo "CPU 15 min平均负载: ${cpu_load[2]}" echo -e "=================================\e[0m"
2. 服务管理脚本
#!/bin/bash # 定义操作数组 oper_array=("启动" "关闭" "重启" "重载" "状态") declare -A cmd_array=(["启动"]="start"["关闭"]="stop"["重启"]="restart"["重载"]="reload"["状态"]="status" )# 显示操作菜单 echo -e "\e[31m-----------服务操作动作-----------" echo " 1: 启动 2: 关闭 3: 重启 4: 重载 5: 状态" echo -e "--------------------------------------\e[0m"# 获取用户输入 read -p "> 请输入操作编号: " oper_num index=$((oper_num-1)) operation=${oper_array[index]}# 显示执行命令 echo -e "\e[32m============服务执行动作============" echo "将执行: systemctl ${cmd_array[$operation]} 服务名" echo -e "======================================\e[0m"
3. 网络连通性测试
#!/bin/bash read -p "输入测试IP: " ip_addr [ -z "$ip_addr" ] && exit 1# 测试网络连通性 ping -c1 -w1 $ip_addr >/dev/null 2>&1 status=$([ $? -eq 0 ] && echo "正常" || echo "异常")# 结果输出 echo -e "\e[31m\t网络状态检测\e[0m" echo -e "\e[32m================================" echo "$ip_addr 状态: $status" echo -e "================================\e[0m"
五、Shell编程最佳实践
-
表达式选择原则
-
文件操作:优先使用文件表达式
-f, -d
-
数值比较:使用数字表达式
-eq, -gt
-
字符串处理:使用字符串表达式
==, !=
-
复杂逻辑:使用组合表达式
&&, ||
-
-
数组使用技巧
# 遍历数组最佳方式 for item in "${array[@]}"; doecho "处理: $item" done# 获取数组最后元素 last_item=${array[-1]}# 数组切片 echo ${array[@]:1:3} # 从索引1开始取3个元素
-
错误处理增强
set -euo pipefail # 启用严格模式 trap 'echo "错误发生在行 $LINENO"' ERR # 错误捕获