跳到主要内容
Linux Shell 脚本中的 for 循环语句详解 | 极客日志
Shell / Bash
Linux Shell 脚本中的 for 循环语句详解 Shell 脚本 for 循环用于重复执行代码块,支持列表遍历、通配符匹配及 C 风格语法。文章详解基础语法、批量文件处理、系统监控及数据库备份等应用场景,并与 Java 进行对比以建立跨语言思维模型。同时涵盖性能优化、错误处理、安全实践及与 Docker 和 Kubernetes 的集成方案,提供自动化运维参考。
观心 发布于 2026/3/25 更新于 2026/6/9 22 浏览Linux Shell 脚本中的 for 循环语句
在 Linux 世界中,Shell 脚本是系统管理员和开发者不可或缺的利器。而其中的 for 循环语句,作为流程控制结构的核心之一,为我们提供了强大的批量处理能力。
什么是 Shell 中的 for 循环?
在 Shell 脚本中,for 循环是一种用于重复执行一段代码块的控制结构。它允许我们遍历一组值(如数字序列、文件列表、命令输出等),并对每个值执行相同或相似的操作。
最基本的 for 循环语法如下:
for variable in list do commands done
这里的 variable 是循环变量,list 是要遍历的值列表,commands 是每次迭代要执行的命令集合。
让我们从一个最简单的例子开始:
#!/bin/bash
for i in 1 2 3 4 5
do
echo "当前数字:$i "
done
运行结果:
当前数字:1
当前数字:2
当前数字:3
当前数字:4
当前数字:5
基础语法详解
1. 列表式 for 循环
这是最直观的形式,直接列出要遍历的所有值:
#!/bin/bash
for fruit in apple banana orange grape
do
echo "我喜欢吃 $fruit "
done
2. 使用通配符遍历文件
Shell 的强大之处在于可以直接使用通配符来匹配文件:
#!/bin/bash
echo "当前目录下的 .txt 文件:"
for file in *.txt
do
if [ -f "$file " ]; then
echo "文件名: "
-l
$file
wc
"$file "
fi
done
3. C 风格的 for 循环 Bash 还支持类似 C 语言的 for 循环语法:
#!/bin/bash
for ((i=1 ; i<=10 ; i++))
do
echo "第 $i 次迭代"
done
这种语法特别适合需要精确控制循环次数和步长的场景。
4. 使用 seq 命令生成序列 seq 命令可以生成数字序列,常与 for 循环配合使用:
#!/bin/bash
for i in $(seq 1 10)
do
echo "数字:$i "
done
echo "---"
for i in $(seq 0 2 10)
do
echo "偶数:$i "
done
实际应用场景
批量文件处理 #!/bin/bash
counter=1
for image in *.jpg *.png *.gif
do
if [ -f "$image " ]; then
extension="${image##*.} "
new_name="photo_${counter} .${extension} "
mv "$image " "$new_name "
echo "已重命名:$image -> $new_name "
((counter++))
fi
done
系统监控脚本 创建一个简单的系统监控脚本,定期检查多个服务的状态:
#!/bin/bash
services=("nginx" "mysql" "redis" "apache2" )
echo "=== 服务状态检查 ==="
for service in "${services[@]} "
do
if systemctl is-active --quiet "$service " ; then
echo "✅ $service 正在运行"
else
echo "❌ $service 未运行"
fi
done
数据库备份脚本 #!/bin/bash
databases=("users_db" "products_db" "orders_db" "logs_db" )
backup_dir="/backups/$(date +%Y%m%d) "
mkdir -p "$backup_dir "
for db in "${databases[@]} "
do
backup_file="$backup_dir /${db} _$(date +%H%M%S) .sql"
mysqldump -u root -p"$MYSQL_PASSWORD " "$db " > "$backup_file "
if [ $? -eq 0 ]; then
echo "✅ $db 备份成功:$backup_file "
gzip "$backup_file "
else
echo "❌ $db 备份失败"
fi
done
与 Java 的对比 为了更好地理解 Shell 中的 for 循环,让我们将其与 Java 中的对应结构进行对比。
基础 for 循环对比 #!/bin/bash
for i in 1 2 3 4 5
do
echo "数字:$i "
done
public class ForLoopExample {
public static void main (String[] args) {
for (int i = 1 ; i <= 5 ; i++) {
System.out.println("数字:" + i);
}
}
}
数组遍历对比 #!/bin/bash
fruits=("apple" "banana" "orange" "grape" )
for fruit in "${fruits[@]} "
do
echo "水果:$fruit "
done
public class ArrayTraversal {
public static void main (String[] args) {
String[] fruits = {"apple" , "banana" , "orange" , "grape" };
for (int i = 0 ; i < fruits.length; i++) {
System.out.println("水果:" + fruits[i]);
}
System.out.println("---" );
for (String fruit : fruits) {
System.out.println("水果:" + fruit);
}
}
}
文件处理对比 #!/bin/bash
for file in *.txt
do
if [ -f "$file " ]; then
echo "处理文件:$file "
wc -l "$file "
fi
done
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
public class FileProcessing {
public static void main (String[] args) {
File directory = new File ("." );
File[] txtFiles = directory.listFiles((dir, name) -> name.endsWith(".txt" ));
if (txtFiles != null ) {
for (File file : txtFiles) {
if (file.isFile()) {
System.out.println("处理文件:" + file.getName());
try {
long lineCount = Files.lines(Paths.get(file.getAbsolutePath())).count();
System.out.println("行数:" + lineCount);
} catch (IOException e) {
System.err.println("读取文件失败:" + e.getMessage());
}
}
}
}
}
}
复杂数据结构处理对比 #!/bin/bash
declare -A student_scores
student_scores["张三" ]=85
student_scores["李四" ]=92
student_scores["王五" ]=78
student_scores["赵六" ]=96
echo "学生成绩统计:"
for student in "${!student_scores[@]} "
do
score=${student_scores[$student]}
grade=""
if [ $score -ge 90 ]; then
grade="A"
elif [ $score -ge 80 ]; then
grade="B"
elif [ $score -ge 70 ]; then
grade="C"
else
grade="D"
fi
echo "$student : $score 分 - $grade 等级"
done
import java.util.HashMap;
import java.util.Map;
public class StudentGrades {
public static void main (String[] args) {
Map<String, Integer> studentScores = new HashMap <>();
studentScores.put("张三" , 85 );
studentScores.put("李四" , 92 );
studentScores.put("王五" , 78 );
studentScores.put("赵六" , 96 );
System.out.println("学生成绩统计:" );
for (Map.Entry<String, Integer> entry : studentScores.entrySet()) {
String student = entry.getKey();
int score = entry.getValue();
String grade;
if (score >= 90 ) {
grade = "A" ;
} else if (score >= 80 ) {
grade = "B" ;
} else if (score >= 70 ) {
grade = "C" ;
} else {
grade = "D" ;
}
System.out.println(student + ": " + score + " 分 - " + grade + " 等级" );
}
}
}
高级技巧和最佳实践
1. 使用 IFS 控制字段分隔符 #!/bin/bash
data="apple,banana,orange,grape"
OLD_IFS=$IFS
IFS=','
for item in $data
do
echo "水果:$item "
done
IFS=$OLD_IFS
2. 嵌套 for 循环 #!/bin/bash
echo "九九乘法表:"
for i in {1..9}
do
for j in {1..9}
do
if [ $j -le $i ]; then
printf "%d×%d=%-2d " $j $i $((i*j))
fi
done
echo
done
3. 使用 break 和 continue #!/bin/bash
echo "查找第一个能被 7 整除的数字:"
for i in {1..100}
do
if [ $((i % 7 )) -eq 0 ]; then
echo "找到:$i "
break
fi
done
echo "---"
echo "跳过能被 3 整除的数字:"
for i in {1..20}
do
if [ $((i % 3 )) -eq 0 ]; then
continue
fi
echo "$i "
done
4. 并行处理 #!/bin/bash
max_jobs=4
job_count=0
files=("file1.txt" "file2.txt" "file3.txt" "file4.txt" "file5.txt" )
for file in "${files[@]} "
do
process_file () {
local f=$1
echo "开始处理 $f "
sleep 2
echo "完成处理 $f "
}
process_file "$file " &
((job_count++))
if [ $job_count -ge $max_jobs ]; then
wait
job_count=0
fi
done
wait
echo "所有文件处理完成!"
性能优化技巧
1. 避免在循环中执行昂贵操作 #!/bin/bash
for i in {1..1000}
do
current_date=$(date )
echo "处理第 $i 项 - $current_date "
done
current_date=$(date )
for i in {1..1000}
do
echo "处理第 $i 项 - $current_date "
done
2. 使用内置命令而非外部命令 #!/bin/bash
for i in {1..1000}
do
result=$(expr $i \* 2)
done
for i in {1..1000}
do
result=$((i * 2 ))
done
3. 批量处理而非逐个处理 #!/bin/bash
for file in *.log
do
rm "$file "
done
rm *.log
错误处理和调试
1. 添加错误检查 #!/bin/bash
set -e
files=("important.txt" "critical.txt" "essential.txt" )
for file in "${files[@]} "
do
if [ ! -f "$file " ]; then
echo "⚠️ 警告:文件 $file 不存在" >&2
continue
fi
if ! cp "$file " "${file} .bak" ; then
echo "❌ 错误:无法备份文件 $file " >&2
exit 1
fi
echo "✅ 成功备份:$file "
done
2. 使用调试模式 #!/bin/bash
set -x
for i in {1..5}
do
echo "迭代 $i "
result=$((i * i))
echo "平方:$result "
done
set +x
3. 日志记录 #!/bin/bash
LOG_FILE="/var/log/my_script.log"
log_message () {
local level=$1
local message=$2
local timestamp=$(date '+%Y-%m-%d %H:%M:%S' )
echo "[$timestamp ] [$level ] $message " | tee -a "$LOG_FILE "
}
directories=("/home/user/docs" "/home/user/pictures" "/home/user/music" )
for dir in "${directories[@]} "
do
if [ -d "$dir " ]; then
file_count=$(find "$dir " -type f | wc -l)
log_message "INFO" "目录 $dir 包含 $file_count 个文件"
else
log_message "WARNING" "目录 $dir 不存在"
fi
done
实际项目案例研究
自动化部署脚本 #!/bin/bash
APP_NAME="my-web-app"
VERSION="1.0.0"
SERVERS=("server1.example.com" "server2.example.com" "server3.example.com" )
DEPLOY_DIR="/opt/$APP_NAME "
BACKUP_DIR="/backup/$APP_NAME "
deploy_to_server () {
local server=$1
local version=$2
echo "🚀 开始部署到 $server "
ssh "$server " "mkdir -p $BACKUP_DIR "
if ssh "$server " "[ -d $DEPLOY_DIR ]" ; then
backup_name="${APP_NAME} _$(date +%Y%m%d_%H%M%S) "
ssh "$server " "cp -r $DEPLOY_DIR $BACKUP_DIR /$backup_name "
echo "✅ 已备份现有应用到 $BACKUP_DIR /$backup_name "
fi
scp -r "./build/$APP_NAME -$version " "$server :$DEPLOY_DIR "
ssh "$server " "chown -R www-data:www-data $DEPLOY_DIR "
ssh "$server " "chmod -R 755 $DEPLOY_DIR "
ssh "$server " "systemctl restart $APP_NAME "
if ssh "$server " "systemctl is-active $APP_NAME " >/dev/null 2>&1; then
echo "🎉 部署成功:$server "
return 0
else
echo "❌ 部署失败:$server "
return 1
fi
}
echo "📦 开始部署 $APP_NAME 版本 $VERSION "
success_count=0
for server in "${SERVERS[@]} "
do
if deploy_to_server "$server " "$VERSION " ; then
((success_count++))
else
echo "⚠️ 跳过后续服务器,因为 $server 部署失败"
break
fi
done
echo "📊 部署统计:$success_count /${#SERVERS[@]} 台服务器成功"
if [ $success_count -eq ${#SERVERS[@]} ]; then
echo "✅ 所有服务器部署成功!"
exit 0
else
echo "❌ 部分服务器部署失败!"
exit 1
fi
数据分析脚本 #!/bin/bash
DATA_DIR="./sales_data"
REPORT_DIR="./reports"
CURRENT_DATE=$(date +%Y%m%d)
mkdir -p "$REPORT_DIR "
data_files=("$DATA_DIR " /*.csv)
if [ ${#data_files[@]} -eq 0 ] || [ ! -f "${data_files[0]} " ]; then
echo "❌ 没有找到销售数据文件"
exit 1
fi
echo "📈 开始分析销售数据..."
total_sales=0
total_transactions=0
best_seller=""
max_sales=0
for file in "${data_files[@]} "
do
if [ ! -f "$file " ]; then
continue
fi
echo "📄 处理文件:$(basename "$file " ) "
while IFS=',' read -r product quantity price date
do
if [ "$product " == "Product" ]; then
continue
fi
sale_amount=$(awk "BEGIN {printf \"%.2f\", $quantity * $price }" )
total_sales=$(awk "BEGIN {printf \"%.2f\", $total_sales + $sale_amount }" )
((total_transactions++))
if (( $(echo "$sale_amount > $max_sales " | bc -l) )); then
max_sales=$sale_amount
best_seller="$product "
fi
done < "$file "
done
REPORT_FILE="$REPORT_DIR /sales_report_$CURRENT_DATE .txt"
{
echo "📊 销售数据分析报告"
echo "📅 生成日期:$(date) "
echo ""
echo "💰 总销售额:\$$total_sales "
echo "🛒 总交易数:$total_transactions "
echo "🏆 最佳销售产品:$best_seller (\$$max_sales )"
if [ $total_transactions -gt 0 ]; then
avg_sale=$(awk "BEGIN {printf \"%.2f\", $total_sales / $total_transactions }" )
echo "📈 平均每笔交易额:\$$avg_sale "
fi
echo ""
echo "📈 详细数据:"
declare -A product_sales
declare -A product_counts
for file in "${data_files[@]} "
do
if [ ! -f "$file " ]; then
continue
fi
while IFS=',' read -r product quantity price date
do
if [ "$product " == "Product" ]; then
continue
fi
sale_amount=$(awk "BEGIN {printf \"%.2f\", $quantity * $price }" )
if [ -z "${product_sales[$product]} " ]; then
product_sales[$product ]=0
product_counts[$product ]=0
fi
product_sales[$product ]=$(awk "BEGIN {printf \"%.2f\", ${product_sales[$product]} + $sale_amount }" )
((product_counts[$product ]++))
done < "$file "
done
echo "🏆 产品销售排行榜:"
for product in "${!product_sales[@]} "
do
echo " $product : ${product_sales[$product]} (${product_counts[$product]} 笔交易)"
done | sort -t '$' -k2 -nr
} > "$REPORT_FILE "
echo "✅ 报告已生成:$REPORT_FILE "
echo "📁 报告内容:"
cat "$REPORT_FILE "
与其他循环结构的比较 除了 for 循环,Shell 脚本还提供了 while 和 until 循环。了解它们的区别有助于选择最适合的循环结构。
for vs while 循环 #!/bin/bash
echo "=== for 循环示例 ==="
for i in {1..5}
do
echo "for 循环:$i "
done
echo "=== while 循环示例 ==="
i=1
while [ $i -le 5 ]
do
echo "while 循环:$i "
((i++))
done
实际应用对比 #!/bin/bash
echo "🍎 水果列表:"
fruits=("apple" "banana" "orange" "grape" )
for fruit in "${fruits[@]} "
do
echo "- $fruit "
done
echo ""
echo "🔄 用户输入处理:"
echo "请输入数字(输入 'quit' 退出):"
while true
do
read -p "> " input
if [ "$input " = "quit" ]; then
break
elif [[ "$input " =~ ^[0-9]+$ ]]; then
echo "您输入了数字:$input "
else
echo "请输入有效数字或 'quit'"
fi
done
echo ""
echo "📄 文件内容处理:"
echo "使用 while 循环:"
while IFS= read -r line
do
echo "行:$line "
done < sample.txt
echo ""
echo "使用 for 循环:"
lines=$(cat sample.txt)
for line in $lines
do
echo "行:$line "
done
常见陷阱和解决方案
1. 文件名包含空格的问题 #!/bin/bash
for file in $(ls )
do
echo "处理:$file "
done
for file in *
do
if [ -f "$file " ]; then
echo "处理:$file "
fi
done
while IFS= read -r -d '' file
do
echo "处理:$file "
done < <(find . -maxdepth 1 -type f -print0)
2. 数组遍历的正确方式 #!/bin/bash
array=("item 1" "item 2" "item 3" )
for item in $array
do
echo "$item "
done
for item in "${array[@]} "
do
echo "$item "
done
for i in "${!array[@]} "
do
echo "索引 $i : ${array[i]} "
done
3. 变量作用域问题 #!/bin/bash
counter=0
echo -e "line1\nline2\nline3" | while read line
do
((counter++))
echo "处理:$line "
done
echo "总计:$counter "
counter=0
while read line
do
((counter++))
echo "处理:$line "
done < <(echo -e "line1\nline2\nline3" )
echo "总计:$counter "
process_lines () {
local count=0
while read line
do
((count++))
echo "处理:$line "
done
echo $count
}
counter=$(echo -e "line1\nline2\nline3" | process_lines)
echo "总计:$counter "
与外部工具的集成
1. 与 awk 集成 #!/bin/bash
echo "📊 销售数据分析:"
for file in sales_*.csv
do
if [ -f "$file " ]; then
echo "📁 处理文件:$file "
total=$(awk -F',' 'NR>1 {sum += $2 * $3} END {printf "%.2f", sum}' "$file " )
top_product=$(awk -F',' 'NR>1 && $3>max {max=$3; product=$1} END {print product}' "$file " )
echo "💰 总销售额:\$$total "
echo "🏆 最高单价产品:$top_product "
echo "---"
fi
done
2. 与 sed 集成 #!/bin/bash
echo "🔄 批量文本替换:"
extensions=("html" "css" "js" )
old_text="old-domain.com"
new_text="new-domain.com"
for ext in "${extensions[@]} "
do
for file in *."$ext "
do
if [ -f "$file " ]; then
echo "📝 处理:$file "
sed -i "s/$old_text /$new_text /g" "$file "
fi
done
done
echo "✅ 所有文件处理完成!"
3. 与 grep 集成 #!/bin/bash
echo "🔍 日志分析:"
log_files=("app.log" "error.log" "access.log" )
search_patterns=("ERROR" "WARNING" "CRITICAL" )
for log_file in "${log_files[@]} "
do
if [ -f "$log_file " ]; then
echo "📄 分析日志文件:$log_file "
for pattern in "${search_patterns[@]} "
do
count=$(grep -c "$pattern " "$log_file " )
if [ $count -gt 0 ]; then
echo " $pattern : $count 次"
echo " 示例:"
grep "$pattern " "$log_file " | head -3 | sed 's/^/ /'
fi
done
echo "---"
fi
done
跨平台兼容性考虑 虽然本文主要关注 Linux Shell,但在编写脚本时也需要考虑跨平台兼容性。
1. Bash vs POSIX Shell #!/bin/bash
for ((i=0 ; i<10 ; i++)); do
echo $i
done
i=0
while [ $i -lt 10 ]; do
echo $i
i=$((i + 1 ))
done
2. 命令差异处理 #!/bin/bash
OS=$(uname -s)
case $OS in
Linux*) DATE_CMD="date -d" ;;
Darwin*)
DATE_CMD="date -j -f" ;;
*)
echo "不支持的操作系统:$OS "
exit 1
;;
esac
for day in {1..7}
do
case $OS in
Linux*) formatted_date=$(date -d "$day days ago" +%Y-%m-%d);;
Darwin*) formatted_date=$(date -j -v-${day} d +%Y-%m-%d);;
esac
echo "日期:$formatted_date "
done
测试和验证策略
1. 单元测试脚本 #!/bin/bash
test_count=0
pass_count=0
assert_equal () {
local expected="$1 "
local actual="$2 "
local message="$3 "
((test_count++))
if [ "$expected " = "$actual " ]; then
echo "✅ PASS: $message "
((pass_count++))
else
echo "❌ FAIL: $message "
echo " 期望:'$expected '"
echo " 实际:'$actual '"
fi
}
test_for_loop_basic () {
result=""
for i in 1 2 3
do
result="$result$i "
done
assert_equal "123" "$result " "基本 for 循环"
}
test_array_iteration () {
arr=("a" "b" "c" )
result=""
for item in "${arr[@]} "
do
result="$result$item "
done
assert_equal "abc" "$result " "数组遍历"
}
echo "🧪 运行测试套件..."
test_for_loop_basic
test_array_iteration
echo "📊 测试结果:$pass_count /$test_count 通过"
if [ $pass_count -eq $test_count ]; then
echo "🎉 所有测试通过!"
exit 0
else
echo "❌ 存在失败的测试!"
exit 1
fi
2. 性能基准测试 #!/bin/bash
benchmark_for_loops () {
local iterations=10000
echo "⏱️ 性能基准测试 ($iterations 次迭代)"
echo ""
start_time=$(date +%s%3N)
for ((i=0 ; i<iterations; i++)); do
:
done
end_time=$(date +%s%3N)
c_style_time=$((end_time - start_time))
echo "C 风格 for 循环:${c_style_time} ms"
start_time=$(date +%s%3N)
for i in $(seq 1 $iterations ); do
:
done
end_time=$(date +%s%3N)
list_style_time=$((end_time - start_time))
echo "列表 for 循环:${list_style_time} ms"
start_time=$(date +%s%3N)
i=0
while [ $i -lt $iterations ]; do
((i++))
done
end_time=$(date +%s%3N)
while_style_time=$((end_time - start_time))
echo "while 循环:${while_style_time} ms"
echo ""
echo "🏆 最快的方法: "
min_time=$c_style_time
fastest="C 风格 for 循环"
if [ $list_style_time -lt $min_time ]; then
min_time=$list_style_time
fastest="列表 for 循环"
fi
if [ $while_style_time -lt $min_time ]; then
min_time=$while_style_time
fastest="while 循环"
fi
echo "$fastest (${min_time} ms)"
}
benchmark_for_loops
安全最佳实践
1. 输入验证 #!/bin/bash
validate_input () {
local input="$1 "
local pattern="$2 "
local description="$3 "
if [[ ! "$input " =~ $pattern ]]; then
echo "❌ 无效的 $description : '$input '" >&2
return 1
fi
return 0
}
safe_file_processing () {
local pattern="$1 "
shift
for filename in "$@ "
do
if ! validate_input "$filename " '^[a-zA-Z0-9._-]+$' "文件名" ; then
continue
fi
if [ ! -f "$filename " ]; then
echo "⚠️ 文件不存在:$filename " >&2
continue
fi
if [ ! -r "$filename " ]; then
echo "⚠️ 文件不可读:$filename " >&2
continue
fi
echo "✅ 安全处理:$filename "
done
}
safe_file_processing "*.txt" "file1.txt" "file with spaces.txt" "dangerous;rm -rf /.txt"
2. 权限检查 #!/bin/bash
check_permissions () {
local required_permission="$1 "
shift
for item in "$@ "
do
case $required_permission in
"read" )
if [ ! -r "$item " ]; then
echo "❌ 缺少读取权限:$item " >&2
return 1
fi
;;
"write" )
if [ ! -w "$item " ]; then
echo "❌ 缺少写入权限:$item " >&2
return 1
fi
;;
"execute" )
if [ ! -x "$item " ]; then
echo "❌ 缺少执行权限:$item " >&2
return 1
fi
;;
esac
done
return 0
}
secure_deploy () {
local servers=("$@ " )
echo "🔒 安全检查..."
if [ ! -f ~/.ssh/id_rsa ] && [ ! -f ~/.ssh/id_ed25519 ]; then
echo "❌ 未找到 SSH 私钥" >&2
return 1
fi
for server in "${servers[@]} "
do
if ! ping -c 1 -W 2 "$server " >/dev/null 2>&1; then
echo "❌ 服务器不可达:$server " >&2
return 1
fi
done
echo "✅ 安全检查通过"
for server in "${servers[@]} "
do
echo "🚀 部署到:$server "
done
}
secure_deploy "server1.example.com" "server2.example.com"
未来趋势和发展 随着 DevOps 和自动化运维的普及,Shell 脚本中的 for 循环也在不断演进。现代 Shell 脚本越来越多地与容器技术、云服务和 CI/CD 管道集成。
1. 与 Docker 集成 #!/bin/bash
manage_containers () {
action="$1 "
shift
containers=("$@ " )
case $action in
"start" )
for container in "${containers[@]} "
do
if docker inspect "$container " >/dev/null 2>&1; then
echo "▶️ 启动容器:$container "
docker start "$container "
else
echo "❌ 容器不存在:$container "
fi
done
;;
"stop" )
for container in "${containers[@]} "
do
if docker ps -q --filter "name=$container " | grep -q .; then
echo "⏹️ 停止容器:$container "
docker stop "$container "
else
echo "⚠️ 容器未运行:$container "
fi
done
;;
"logs" )
for container in "${containers[@]} "
do
echo "📋 容器日志:$container "
docker logs --tail 10 "$container "
echo "---"
done
;;
esac
}
containers=("web-server" "database" "cache" "worker" )
echo "🐳 Docker 容器管理"
manage_containers "logs" "${containers[@]} "
2. 与 Kubernetes 集成 #!/bin/bash
kubectl_batch_operations () {
namespace="$1 "
operation="$2 "
shift 2
resources=("$@ " )
echo "☸️ Kubernetes $operation 操作 (命名空间:$namespace )"
for resource in "${resources[@]} "
do
case $operation in
"scale" )
replicas="$resource "
deployments=$(kubectl get deployments -n "$namespace " -ojsonpath='{.items[*].metadata.name}' )
for deployment in $deployments
do
echo "📏 扩展部署 $deployment 到 $replicas 个副本"
kubectl scale deployment "$deployment " --replicas="$replicas " -n "$namespace "
done
;;
"restart" )
echo "🔄 重启部署:$resource "
kubectl rollout restart deployment "$resource " -n "$namespace "
;;
"status" )
echo "📊 部署状态:$resource "
kubectl get deployment "$resource " -n "$namespace "
kubectl get pods -l app="$resource " -n "$namespace "
;;
esac
done
}
kubectl_batch_operations "production" "status" "frontend" "backend" "database"
总结 Shell 脚本中的 for 循环是一个强大而灵活的工具,它使我们能够自动化重复性任务、批量处理数据、管理系统资源。通过本文的详细介绍,我们了解了:
基础语法 :从简单的列表遍历到复杂的 C 风格循环
实际应用 :文件处理、系统监控、数据备份等真实场景
性能优化 :避免常见性能陷阱,编写高效的循环代码
错误处理 :添加健壮的错误检查和日志记录
安全实践 :确保脚本的安全性和可靠性
现代集成 :与 Docker、Kubernetes 等现代技术的结合
无论你是系统管理员、DevOps 工程师还是普通开发者,掌握 Shell 脚本中的 for 循环都将大大提升你的工作效率。记住,最好的学习方式是实践 - 从今天开始,尝试将你日常工作中的重复任务自动化吧!
相关免费在线工具 Base64 字符串编码/解码 将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
Base64 文件转换器 将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
Markdown转HTML 将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
HTML转Markdown 将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
JSON 压缩 通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
JSON美化和格式化 将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online