主题
  • 默认模式
  • 浅蓝色模式
  • 淡绿色模式
  • 深夜模式

Shell 流程控制

JavaPHP 等语言不同,sh 的流程控制结构不能为空语句。例如(以下为 PHP 的流程控制写法):

php
复制
<?php
if (isset($_GET["keywords"])) {
    search(keywords);
} else {
    // 不做任何事情
}

sh/bash中不可以这样写——如果else分支没有要执行的语句,就不不需要编写这个else了。


条件判断 (if, case)

条件判断用于控制程序流程,根据表达式的真假结果选择不同的分支路径执行。

1. if 语句

✅ 在sh/bash中,if语句的语法如下:

if [ condition ]; then
  # 条件为真时执行的命令
elif [ another_condition ]; then
  # 另一个条件为真时执行的命令
else
  # 所有条件都为假时执行的命令
fi

✅ 语法解释说明:

  • ifthen可以写在同一行,用分号;分隔。
  • 条件判断语句[ condition ]的两边必须有空格。
  • 使用fi结束整个if语句块。

✅ 下面是一个简单的示例:

bash
复制
#!/bin/bash
# author: 开创者教程
# url: www.kaicz.com

read -p "请输入一个数字: " num

# 使用 (( )) 进行算术比较
if (( num > 100 )); then
  echo "数字大于 100"
elif (( num >= 50 )); then
  echo "数字在 50 到 100 之间"
else
  echo "数字小于 50"
fi

# 检查文件是否存在
file="/etc/passwd"
if [[ -f $file ]] && [[ -r $file ]]; then
  echo "$file 存在且可读"
else
  echo "$file 不存在或不可读"
fi

2. case 语句

✅ 在sh/bash中,case语句用于匹配一个值与多个模式,比多个if-elif更清晰,语法如下:

case $variable in
  pattern1)
    # 匹配 pattern1 后执行的命令
    ;;
  pattern2|pattern3)
    # 匹配 pattern2 或 pattern3 后执行的命令
    ;;
  *)
    # 默认情况,匹配任何其他值
    ;;
esac

✅ 语法解释说明:

  • 每个模式分支以)结束。
  • 命令块以;;结束,代表break
  • *) 是默认情况(类似于switch中的 default)。
  • 使用esac结束整个case语句。

✅ 下面是一个简单的示例:

bash
复制
#!/bin/bash
# author: 开创者教程
# url: www.kaicz.com

echo "请选择操作:"
echo "1) 启动服务"
echo "2) 停止服务"
echo "3) 重启服务"
read -p "请输入数字 (1-3): " choice

case $choice in
  1)
    echo "正在启动服务..."
    # systemctl start someservice
    ;;
  2)
    echo "正在停止服务..."
    # systemctl stop someservice
    ;;
  3)
    echo "正在重启服务..."
    # systemctl restart someservice
    ;;
  *)
    echo "输入错误,请输入 1, 2 或 3."
    exit 1
    ;;
esac

循环 (for, while, until)

循环是一种编程机制,用于自动重复执行特定操作或命令序列。

1. for 循环

用于自动按顺序访问列表中的每一个项目,直至所有项目处理完毕。语法如下:

for variable in item1 item2 ... itemN
do
  # 循环体,使用 $variable
done

或者

for (( initializer; condition; increment ))
do
  # 循环体
done

✅ 下面是一个简单的示例:

bash
复制
#!/bin/bash
# author: 开创者教程
# url: www.kaicz.com

# 示例 1:遍历字符串列表
for fruit in apple banana orange
do
  echo "I like $fruit"
done

# 示例 2:遍历命令输出结果(例如 ls 列出的文件)
for file in $(ls *.txt)
do
  echo "处理文件: $file"
  # cp "$file" "/backup/$file.bak"
done

# 示例 3:C 语言风格循环
for (( i=1; i<=5; i++ ))
do
  echo "这是第 $i 次循环"
done

2. while 循环

只要条件为真,就持续执行循环。语法如下:

while [ condition ]
do
  # 循环体
done

✅ 下面是一个简单的示例:

bash
复制
#!/bin/bash
# author: 开创者教程
# url: www.kaicz.com

# 示例 1:计数器
count=1
while [ $count -le 5 ]
do
  echo "Count: $count"
  ((count++)) # 另一种写法:count=$((count + 1))
done

# 示例 2:读取文件每一行(经典用法)
while IFS= read -r line
do
  echo "行内容: $line"
done < /etc/passwd # 输入重定向到循环
# IFS= 防止行首尾空格被修剪
# -r 防止反斜杠转义被解释

3. until 循环

while相反,只要条件为假,就持续执行循环。直到条件为真时停止。语法如下:

until [ condition ]
do
  # 循环体
done

✅ 下面是一个简单的示例:

bash
复制
#!/bin/bash
# author: 开创者教程
# url: www.kaicz.com

# 等待某个服务启动,或者等待某个文件被创建
count=0
until [ $count -ge 5 ]
do
  echo "等待中... ($count)"
  ((count++))
  sleep 1
done
echo "等待结束!"

循环控制 (break, continue)

循环控制语句用于在循环中改变执行流程:

  • break:立即终止整个循环,跳出执行done 之后的命令。break n 可以跳出 n 层循环。
  • continue:跳过当前循环中剩余的指令,直接开始下一次循环。
bash
复制
#!/bin/bash
# author: 开创者教程
# url: www.kaicz.com

# break 示例:找到第一个 .txt 文件就停止
for file in *
do
  if [[ $file == *.txt ]]; then
    echo "找到第一个文本文件: $file"
    break # 找到后就跳出循环
  fi
done

# continue 示例:只处理非 .tmp 的文件
for file in *
do
  if [[ $file == *.tmp ]]; then
    continue # 跳过临时文件,继续下一个
  fi
  echo "正在处理重要文件: $file"
doneecho "等待结束!"


评论区 0
发表评论