Shell 循环编程:for 与 select 轻松入门
Shell 循环编程:for 与 select 轻松入门
前言
在 Shell 脚本中,for
和 select
循环是两种非常实用的循环结构。for
循环特别适合处理已知循环次数的任务,而 select
循环则是创建交互式菜单的神器。让我们通过一些有趣的示例来轻松掌握它们吧!
1. for 循环:你的批量处理小助手
for 循环主要有两种语法格式,满足不同场景的需求。
1.1 变量取值型 for 循环
语法结构:
bash
for 变量名 in 变量取值列表
do指令...
done
小贴士:
- 如果省略
in 变量取值列表
,相当于使用in "$@"
(即所有位置参数) - 执行过程:变量会依次获取列表中的每个值,执行循环体,直到所有值取完
示例 1:基础数字打印
bash
#!/bin/bash
# 方法一:使用花括号扩展
echo "方法一:花括号扩展"
for i in {1..5}
doecho $i
done# 方法二:使用 seq 命令
echo -e "\n方法二:seq 命令"
for i in $(seq 5)
doecho $i
done# 方法三:C语言风格
echo -e "\n方法三:C语言风格"
for ((i=1; i<=5; i++))
doecho $i
done
示例 2:倒序打印数字
bash
#!/bin/bash
# 方法一:花括号倒序
echo "倒序打印:"
for i in {5..1}
doecho $i
done# 方法二:seq 命令倒序
echo -e "\n使用 seq 倒序:"
for i in $(seq 5 -1 1)
doecho $i
done
示例 3:实用计算小工具
bash
#!/bin/bash
# 计算 1-10 的和
sum=0
for i in {1..10}
dosum=$((sum + i))
done
echo "1+2+...+10 = $sum"# 计算 10 的阶乘
product=1
for i in {1..10}
doproduct=$((product * i))
done
echo "10! = $product"
1.2 C 语言型 for 循环
语法结构:
bash
for ((exp1; exp2; exp3))
do指令...
done
说明:
exp1
:初始化表达式(如:i=0)exp2
:条件表达式(如:i<10)exp3
:步进表达式(如:i++)
示例 4:寻找水仙花数
bash
#!/bin/bash
# 水仙花数:一个 3 位数,各位数字的立方和等于它本身
echo "水仙花数有:"
for num in {100..999}
don1=$((num / 100)) # 百位数n2=$((num % 100 / 10)) # 十位数n3=$((num % 10)) # 个位数# 计算各位立方和sum=$((n1**3 + n2**3 + n3**3))if [ $sum -eq $num ]; thenecho "$num: $n1³ + $n2³ + $n3³ = $num"fi
done
示例 5:寻找素数
bash
#!/bin/bash
# 素数:只能被 1 和自身整除的大于1的自然数
echo -n "100~200之间的素数有:"
for ((i=100; i<=200; i++))
do# 检查 i 是否为素数is_prime=1for ((j=2; j*j<=i; j++))doif [ $((i % j)) -eq 0 ]; thenis_prime=0breakfidoneif [ $is_prime -eq 1 ]; thenecho -n " $i"fi
done
echo
示例 6:九九乘法表
bash
#!/bin/bash
# 打印九九乘法表
for i in {1..9}
dofor ((j=1; j<=i; j++))do# 格式化输出,保持对齐printf "%d×%d=%-2d " $j $i $((j*i))doneecho
done
1.3 企业级实战案例
案例 1:批量文件操作
bash
#!/bin/bash
# 批量创建测试文件
for i in {1..5}; do touch "file-${i}.txt"; doneecho "创建的文件:"
ls -l file-*.txt# 批量修改文件扩展名 (.txt → .jpg)
echo -e "\n批量修改文件扩展名:"
for file in *.txt
do# 使用字符串替换修改扩展名new_name="${file%.txt}.jpg"mv "$file" "$new_name"echo "重命名: $file → $new_name"
doneecho -e "\n修改后的文件:"
ls -l file-*.jpg
案例 2:批量用户管理
bash
#!/bin/bash
# 批量创建用户并设置随机密码
USER_FILE="/tmp/users"# 创建用户列表文件
cat > $USER_FILE << EOF
laoma
laowang
tony
jack
EOFecho "开始创建用户..."
while read username
do# 生成随机密码(8位字符)password=$(openssl rand -base64 6 | tr -d '/+=' | cut -c1-8)# 创建用户if useradd $username 2>/dev/null; then# 设置密码echo "$password" | passwd --stdin $username >/dev/null 2>&1# 强制首次登录修改密码chage -d 0 $usernameecho "用户 $username 创建成功,初始密码: $password"elseecho "用户 $username 创建失败"fi
done < $USER_FILE
2. select 循环:打造交互式菜单
select 循环专门用于创建简单的文本菜单,让脚本更加交互友好。
2.1 select 循环基础
语法结构:
bash
select 变量名 [ in 菜单项列表 ]
do指令...
done
特点:
- 自动生成带编号的菜单
- 用户输入数字选择对应选项
- 选择的值存储在变量中,选项编号存储在
$REPLY
中 - 默认不会自动退出,需要手动添加退出逻辑
示例 1:基础课程选择
bash
#!/bin/bash
# 简单的课程选择菜单
echo "请选择你想学习的课程:"
select course in "Linux基础" "Python编程" "MySQL数据库" "退出"
docase $course in"Linux基础")echo "你选择了Linux基础课程,这是系统管理的必备技能!";;"Python编程")echo "Python是当下最流行的编程语言之一,好选择!";;"MySQL数据库")echo "数据库管理是后端开发的核心技能。";;"退出")echo "再见!"exit 0;;*)echo "无效选择,请输入1-4之间的数字";;esacecho -e "\n还想了解其他课程吗?"
done
示例 2:简易计算器
bash
#!/bin/bash
# 简易计算器
echo "欢迎使用简易计算器"# 设置更友好的提示符
PS3="请选择操作(1-5): "# 输入两个数字
read -p "请输入第一个数字: " num1
read -p "请输入第二个数字: " num2select operation in "加法" "减法" "乘法" "除法" "退出"
docase $operation in"加法")result=$((num1 + num2))echo "$num1 + $num2 = $result";;"减法")result=$((num1 - num2))echo "$num1 - $num2 = $result";;"乘法")result=$((num1 * num2))echo "$num1 × $num2 = $result";;"除法")if [ $num2 -eq 0 ]; thenecho "错误:除数不能为0!"elseresult=$(echo "scale=2; $num1 / $num2" | bc)echo "$num1 ÷ $num2 = $result"fi;;"退出")echo "感谢使用计算器!"exit 0;;*)echo "无效选择,请重新输入";;esac
done
示例 3:系统服务管理菜单
bash
#!/bin/bash
# 系统服务管理菜单
echo "系统服务管理"PS3="请选择要操作的服务(1-4): "select service in "nginx" "mysql" "ssh" "退出"
docase $service in"nginx"|"mysql"|"ssh")echo -e "\n=== $service 服务管理 ==="select action in "启动" "停止" "重启" "状态" "返回上级"docase $action in"启动")sudo systemctl start $serviceecho "$service 服务已启动";;"停止")sudo systemctl stop $serviceecho "$service 服务已停止";;"重启")sudo systemctl restart $serviceecho "$service 服务已重启";;"状态")sudo systemctl status $service -l --no-pager;;"返回上级")break;;*)echo "无效选择";;esacdone;;"退出")echo "再见!"exit 0;;*)echo "无效选择,请重新输入";;esacecho -e "\n请选择要操作的服务:"
done
3. 随机数生成技巧
在脚本中生成随机数很有用,特别是在创建密码或测试数据时。
bash
#!/bin/bash
# 多种随机数生成方法演示
echo "=== 随机数生成方法演示 ==="# 方法1:使用系统环境变量 $RANDOM (0-32767)
echo "1. 使用 RANDOM: $RANDOM"# 方法2:使用 openssl(更安全)
echo "2. 使用 openssl: $(openssl rand -base64 8)"# 方法3:使用日期纳秒
echo "3. 使用日期纳秒: $(date +%s%N)"# 方法4:使用 /dev/urandom
echo "4. 使用 /dev/urandom: $(head -c 8 /dev/urandom | base64)"# 方法5:使用 UUID
echo "5. 使用 UUID: $(cat /proc/sys/kernel/random/uuid | cut -c1-8)"# 方法6:使用 mktemp
echo "6. 使用 mktemp: $(mktemp -u | md5sum | cut -c1-8)"echo -e "\n推荐用于密码生成: 方法2或方法4"
总结
for 和 select 循环是 Shell 脚本中极其强大的工具:
- for 循环适合处理:
- 已知迭代次数的任务
- 批量文件操作
- 数据遍历和处理
- select 循环适合:
- 创建交互式菜单
- 构建用户友好的命令行工具
- 需要用户选择的场景
通过本文的示例,你可以看到这两种循环结构的灵活性和强大功能。现在尝试编写你自己的脚本,运用这些技巧解决实际问题吧!
记住,编程最好的学习方式就是实践,多写多练,你一定会成为 Shell 脚本高手!