for 循环

for 循环是 Shell 中最常用的循环结构,适合遍历列表、数组、文件等场景。

基本语法

列表形式

for 变量 in 列表; do
    命令
done

C 语言风格

for ((初始化; 条件; 更新)); do
    命令
done

遍历列表

# 直接列出元素
for FRUIT in apple banana orange; do
    echo "水果: $FRUIT"
done

# 输出:
# 水果: apple
# 水果: banana
# 水果: orange

遍历数组

FRUITS=("apple" "banana" "orange")

for FRUIT in "${FRUITS[@]}"; do
    echo "水果: $FRUIT"
done

注意用 "${FRUITS[@]}" 而不是 ${FRUITS[@]},前者能正确处理包含空格的元素。

遍历命令输出

# 遍历文件
for FILE in $(ls *.txt); do
    echo "处理文件: $FILE"
done

# 遍历目录
for DIR in */; do
    echo "目录: $DIR"
done

# 遍历进程
for PID in $(pgrep nginx); do
    echo "nginx 进程: $PID"
done

遍历数字范围

# 1 到 5
for I in {1..5}; do
    echo "数字: $I"
done

# 指定步长
for I in {1..10..2}; do
    echo "奇数: $I"
done

# 倒序
for I in {5..1}; do
    echo "倒计时: $I"
done

C 风格 for 循环

# 基本用法
for ((I=1; I<=5; I++)); do
    echo "计数: $I"
done

# 多变量
for ((I=0, J=10; I<5; I++, J--)); do
    echo "I=$I, J=$J"
done

# 遍历数组索引
ARR=("a" "b" "c")
for ((I=0; I<${#ARR[@]}; I++)); do
    echo "ARR[$I] = ${ARR[$I]}"
done

遍历文件

# 遍历当前目录的文件
for FILE in *; do
    if [ -f "$FILE" ]; then
        echo "文件: $FILE"
    fi
done

# 遍历指定类型的文件
for FILE in *.txt; do
    echo "处理: $FILE"
    # 处理逻辑
done

# 递归遍历
for FILE in $(find . -name "*.log"); do
    echo "日志文件: $FILE"
done

遍历命令行参数

#!/bin/bash

# 方式一
for ARG in "$@"; do
    echo "参数: $ARG"
done

# 方式二:带索引
for I in ${!@}; do
    echo "参数 $I: ${!I}"
done

嵌套循环

for I in {1..3}; do
    for J in {1..3}; do
        echo "I=$I, J=$J"
    done
done

实际应用

批量重命名

#!/bin/bash

for FILE in *.txt; do
    NEW_NAME="${FILE%.txt}.bak"
    mv "$FILE" "$NEW_NAME"
    echo "重命名: $FILE -> $NEW_NAME"
done

批量处理文件

#!/bin/bash

for FILE in *.log; do
    echo "压缩 $FILE..."
    gzip "$FILE"
done

批量创建用户

#!/bin/bash

USERS=("user1" "user2" "user3")

for USER in "${USERS[@]}"; do
    useradd -m "$USER"
    echo "创建用户: $USER"
done

检查服务状态

#!/bin/bash

SERVICES=("nginx" "mysql" "redis")

for SVC in "${SERVICES[@]}"; do
    if systemctl is-active --quiet "$SVC"; then
        echo "$SVC: 运行中"
    else
        echo "$SVC: 未运行"
    fi
done

批量下载

#!/bin/bash

URLS=(
    "https://example.com/file1.zip"
    "https://example.com/file2.zip"
)

for URL in "${URLS[@]}"; do
    FILENAME=$(basename "$URL")
    wget -O "$FILENAME" "$URL"
done

无限循环

# 方式一
for ((;;)); do
    echo "无限循环"
    sleep 1
done

# 方式二
while true; do
    echo "无限循环"
    sleep 1
done

小结

for 循环要点:

  1. 列表形式适合遍历集合
  2. C 风格适合计数循环
  3. {start..end} 生成数字范围
  4. 数组遍历用 "${ARR[@]}"
  5. 文件遍历用通配符或 find