结构化命令case和for、while循环

1、case 流程控制语句

case 是一种流程控制语句,通常用于根据不同的条件值执行不同的代码块。它的语法如下:

case expression in
    pattern1)
        # 在匹配 pattern1 时执行的代码
        ;;
    pattern2)
        # 在匹配 pattern2 时执行的代码
        ;;
    pattern3)
        # 在匹配 pattern3 时执行的代码
        ;;
    *)
        # 如果没有匹配的模式时执行的代码
        ;;
esac
  • expression 是需要进行匹配的表达式或变量。

  • pattern1pattern2pattern3 等是可能的模式,可以是常量字符串或使用通配符的模式。

  • ;; 用于标记每个模式下的代码块的结束。

  • *) 是一个通配符模式,用于匹配所有未被之前的模式匹配的情况。

image-20230907110532229

例:简单的apache启动脚本

#!/bin/bash
######################################
#filename:httpd start scripts
#author:kc
#date:2023-09-01
######################################
cat << EOF
####################
#     1.start      #
#     2.statas     #
#     3.stop       #
#     4.exit       #
####################
EOFread -p "please input your choose:" OP
case $OP in
        1)
                systemctl start httpd
                ;;
        2)
                systemctl status httpd
                ;;
        3)
                systemctl stop httpd
                ;;
        4)
                exit
                ;;
        *)
                echo error
                ;;
esac

2、for循环语句

for 循环用于迭代一个列表或范围,并对每个元素执行一组命令。Shell支持不同种类的for循环,最常用的有两种:for-in 循环和 for 循环。

1. for-in 循环

for-in 循环用于迭代一个列表中的元素。以下是基本语法:

#!/bin/bash
for variable in list
do
    # 在循环内执行的命令
done
  • variable 是一个变量,用于存储列表中的每个元素。

  • list 是要迭代的元素列表,可以是一组字符串、文件列表等。

示例:

#!/bin/bash
fruits=("apple" "banana" "cherry")

for fruit in "${fruits[@]}"
do
    echo "水果: $fruit"
done

上述代码将迭代 fruits 数组中的每个元素,并将其打印出来。

2. for 循环

for 循环用于迭代一系列数字(通常是一个范围)。以下是基本语法:

for (( init; condition; increment ))
do
    # 在循环内执行的命令
done
  • init 是初始化语句,通常用于设置一个计数器。

  • condition 是循环的条件,循环会一直执行直到条件为假。

  • increment 是在每次迭代后更新计数器的语句。

示例:

#!/bin/bash

for (( i=1; i<=5; i++ ))
do
    echo "迭代次数: $i"
done

上述代码将循环迭代5次,并在每次迭代中打印出迭代次数。

除了上述两种基本循环,还可以使用 seq 命令来生成数字序列并用于循环。例如:

#!/bin/bash

for i in $(seq 1 5)
do
    echo "迭代次数: $i"
done

这将产生与前面示例相同的输出。

无论是 for-in 循环还是 for 循环,都可以用于处理各种迭代任务,例如文件列表的处理、命令的多次执行等。

3、IFS 字段分隔符

字段分隔符 IFS(Internal Field Separator)是一个特殊的环境变量,用于指定字段(单词)在字符串中的分隔符。默认情况下,IFS 包含空格、制表符和换行符,这意味着Shell会将这些字符视为字段分隔符,并用它来拆分字符串。你可以自定义 IFS 的值,以适应你的需求。

1. 默认的 IFS

默认情况下,IFS 包含以下字符:

  • 空格(

  • 制表符(\t

  • 换行符(\n

这意味着当你使用命令像 read 或字符串分割操作时,Shell会使用这些字符来分割输入的字符串。

#!/bin/bash
string="apple banana cherry"
IFS=" " # 设置IFS为单个空格
read -ra fruits <<< "$string"
for fruit in "${fruits[@]}"; do
  echo "$fruit"
done

在上面的示例中,我们将 IFS 设置为单个空格,然后使用 read 命令将字符串 $string 分割成一个数组,并遍历输出。

2. 自定义 IFS

你可以根据需要自定义 IFS 的值,以适应不同的分割字符。例如,如果你有一个以逗号分隔的字符串,你可以将 IFS 设置为逗号来分割它:

#!/bin/bash
csv="apple,banana,cherry"
IFS="," # 设置IFS为逗号
read -ra fruits <<< "$csv"
for fruit in "${fruits[@]}"; do
  echo "$fruit"
done

这将把 $csv 字符串分割成一个逗号分隔的数组。

请注意,自定义 IFS 时要小心,确保它适用于你的特定需求。当不再需要自定义 IFS 时,最好将其还原为默认值,以免影响其他部分的脚本。例如,可以将 IFS 重新设置为默认值:

IFS=$' \t\n' # 将IFS还原为默认值

4、while循环语句

while 循环语句用于在条件满足的情况下重复执行一组命令。循环会一直执行,直到条件不再满足。以下是 while 循环的基本语法:

while [ condition ]
do
    # 在循环内执行的命令
done
  • condition 是一个条件表达式,通常包含了一个命令、比较操作符和值。如果 condition 的结果为真(返回退出状态码为0),则继续执行循环内的命令;如果为假(返回退出状态码为非零),则退出循环。

  • image-20230907115141646

下面是一个简单的示例,演示了如何使用 while 循环来打印数字从1到5:

#!/bin/bash

counter=1

while [ $counter -le 5 ]
do
    echo "Counter is $counter"
    ((counter++))  # 增加计数器的值
done

在上面的示例中,counter 变量用于追踪循环的迭代次数。while 循环的条件是 [ $counter -le 5 ],它检查 counter 是否小于或等于5。只要条件满足,循环就会继续执行,并在每次迭代中打印当前计数器的值。迭代完成后,计数器递增,循环继续,直到条件不再满足。

在实际脚本中,while 循环通常与条件和用户输入等交互操作一起使用,以便在满足特定条件时执行一组命令,例如文件处理、数据处理等任务。

5、嵌套循环

在Shell脚本中,你可以嵌套循环,这意味着你可以在一个循环内包含另一个循环。嵌套循环非常有用,因为它们允许你在内部循环中执行更复杂的操作,而外部循环控制循环的重复次数。以下是一个示例,演示了如何使用嵌套循环:

#!/bin/bash

# 外部循环控制行数
for (( i=1; i<=3; i++ ))
do
    echo "行 $i"

    # 内部循环控制列数
    for (( j=1; j<=4; j++ ))
    do
        echo -n " 列 $j"
    done

    echo  # 换行以分隔行
done

在这个示例中,我们有一个外部 for 循环,用于控制行数(1 到 3)。每次外部循环迭代时,内部有一个 for 循环,用于控制列数(1 到 4)。内部循环在每次外部循环迭代时都会执行一遍。

运行这个脚本将生成如下输出:

行 1 列 1 列 2 列 3 列 4
行 2 列 1 列 2 列 3 列 4
行 3 列 1 列 2 列 3 列 4

这个示例展示了嵌套循环的基本概念,但你可以根据需要调整外部和内部循环的计数器以及执行的命令来实现更复杂的操作。嵌套循环常用于处理多维数据、矩阵、文件处理等情况,其中需要同时控制行和列。

6、break和continue

breakcontinue 关键字来控制循环的行为:

  1. break

    • break 用于立即退出循环,不再执行循环中剩余的代码。

    • 通常,break 用于在满足某个条件时退出循环,以提前结束循环迭代。

示例:

#!/bin/bash

for i in {1..5}
do
    if [ $i -eq 3 ]
    then
        echo "遇到3,退出循环"
        break
    fi
    echo "迭代: $i"
done

在上面的示例中,当循环变量 i 的值等于3时,break 被触发,循环被提前退出。

  1. continue

    • continue 用于跳过当前迭代并继续下一次循环迭代。

    • 通常,continue 用于在某些条件下跳过特定的迭代。

示例:

#!/bin/bash

for i in {1..5}
do
    if [ $i -eq 3 ]
    then
        echo "跳过3,继续下一次迭代"
        continue
    fi
    echo "迭代: $i"
done

在上面的示例中,当循环变量 i 的值等于3时,continue 被触发,跳过了值为3的迭代,然后继续下一次迭代。

breakcontinue 可以在各种循环中使用,包括 for 循环和 while 循环,以控制循环的流程。它们通常用于根据特定条件来管理循环的行为。

7、shift左移命令

shift 命令用于左移命令行参数列表(或位置参数列表)中的参数。它将删除第一个参数,并将其他参数依次左移一个位置。shift 命令通常用于处理命令行参数或选项。

以下是 shift 命令的基本语法:

shift [n]
  • n 是一个可选的参数,表示要左移的位置数。如果不指定 n,则默认为1。

示例:

#!/bin/bash

echo "第一个参数: $1"
echo "第二个参数: $2"
echo "第三个参数: $3"

shift # 默认左移一个位置

echo "左移后的参数列表:"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "第三个参数: $3"

在上面的示例中,我们首先打印出前三个命令行参数的值,然后使用 shift 命令左移了一个位置,将第一个参数删除,并将其他参数左移一个位置。然后我们再次打印参数,可以看到参数列表已经左移了一个位置。

当需要处理多个命令行参数或选项时,shift 命令很有用,因为它允许你依次处理参数列表而不必手动访问每个参数。可以在循环中使用 shift 命令来遍历参数列表,以执行相应的操作。

假设你运行这个脚本,并传递了一些参数:

./myscript.sh apple banana cherry

脚本会首先打印出传递的参数:

第一个参数: apple
第二个参数: banana
第三个参数: cherry

然后,通过使用shift命令左移一个位置,它会删除第一个参数,并将其他参数左移。再次打印参数将显示:

左移后的参数列表:
第一个参数: banana
第二个参数: cherry
第三个参数:

如你所见,第一个参数"apple"被删除了,而其他参数左移了一个位置。这就是shift命令在处理命令行参数时的用法示例。

示例:通过传参做加法运算

1 #!/bin/bash
  2 if [ $# -le 0 ];then
  3         echo "您没有输入参数"
  4 fi
  5 sum=0
  6 while [ $# -gt 0 ];do
  7         sum=$(($sum+$1))
  8         shift
  9 done
 10 echo "result is $sum"

8、实战

例:打包/var/log目录下的log文件,并复制保存在/opt/backup/目录下

#/bin/bash
src=/var/log
des="/opt/backup/$(date +%F)"
if
[ ! -d "$des" ];then
        mkdir -p "$des"
fi
for i in `find $src -name '*.log'`
do
        tar -czf "$i.tar.gz" "$i"
done
find $src -name "*.tar.gz" -exec mv {} $des \;
ls -lh $des
echo "Creating directory: $des"
echo "The scripts exec end ,Files tar sucessfully!"

例:99乘法表

#!/bin/bash
for i in `seq 9`
do
        for j in `seq $i`
        do
        printf "%d * %d = %d\t" "$i" "$j" "$((i*j))"
               #echo -n "$i * $j = $((i*j)) "
                if [ $i -eq $j ];then
                echo 
                fi
        done
done

例:判断192.168.52.0网段主机是否开机

  1 #!/bin/bash
  2 i=1
  3 for ((i=1;i<10;i++))
  4 do
  5 ping -c 3 192.168.52.$i &> /dev/null
  6 if [ $? -ne 0 ];then
  7         echo "192.168.52.$i is shutdown"
  8 fi
  9 done

例:批量创建用户

 1 #!/bin/bash
  2 for i in xuegodc{1..10}
  3 do
  4         useradd $i
  5         pass=$(echo $(date +%s)|md5sum|cut -c 1-8)
  6         sleep 1
  7         echo "$i:$pass" >> /tmp/passwd.log
  8         echo $pass|passwd --stdin $i > /dev/null 2>&1
  9         if [ $? -eq 0 ];then
 10                 echo "Create user $i successfully!"
 11         else
 12                 echo "Create user $i is failed!"
 13         fi
 14 done

例:批量删除用户

  1 #!/bin/bash
  2 for i in xuegodc{1..10}
  3 do
  4         if id $i > /dev/null;then
  5                 userdel -r $i
  6                 sleep 1
  7                 if [ $? -eq 0 ];then
  8                         echo "User $i deleted successfully!"
  9                 else
 10                         echo "Faild to delete user $i"
 11                 fi
 12         fi
 13 done

例:交互式创建用户

  1 #!/bin/bash
  2 while :
  3 do
  4         read -p "Please enter prefix & password &num:" prefix password num
  5         printf "user information:
  6         ************************
  7         user prefix : $prefix
  8         password    : $password
  9         num         : $num
 10         ************************
 11 "
 12   read -p "Are you sure?{Y/N}" action
 13   if [ "$action" == "Y" ] || [ "$action" == "y" ];then
 14         for i in $( seq $num )
 15          do
 16           user=${prefix}${i}
 17           id $user &> /dev/null
 18           if [ $? -ne 0 ] ;then
 19                   useradd $user
 20                   echo "$password" |passwd --stdin $user &> /dev/null
 21                   if [ $? -eq 0 ];then
 22                           echo -e "\033[31m$user\033[m creat"
 23                   fi
 24           else
 25                   echo "user $user exist"
 26           fi
 27           done
 28           break
 29   elif [ "$action" == "N" ] || [ "$action" == "n" ];then
 30           continue
 31   fi
 32 done
posted @   墨香清梦  阅读(351)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示