引言

  在编写程序的世界里,Shell编程作为一种强大的脚本语言,因其在自动化任务和系统管理方面的高效性而备受青睐。Shell脚本能够简化复杂的命令序列,通过一系列的脚本命令来控制和操作系统,使得重复性的任务变得自动化和简单化。而在Shell编程中,循环语句和函数是构建高效脚本的基石,它们为处理重复任务和模块化编程提供了强大的支持。

  循环语句允许我们重复执行一组命令,直到满足特定条件。在Shell脚本中,forwhileuntil循环提供了不同的迭代机制,以适应各种场景。例如,for循环可以用于批量创建用户账户或者检查一系列主机的状态,而whileuntil循环则可以处理那些需要在满足某个条件之前不断重复的任务。

  函数在Shell编程中同样扮演着重要角色。通过定义函数,我们可以将复杂的命令封装起来,使得代码更加模块化和可重用。函数不仅可以简化代码,还可以使得维护和理解脚本变得更加容易。此外,Shell函数支持参数传递,使得我们的脚本更加灵活和强大。

for循环语句

  在Shell编程中,for循环是一种基本的循环控制结构,它允许我们对一组指令进行重复执行。for循环的基本语法非常简洁,其结构如下:

for 变量名 in 取值列表
do
    命令序列
done

  在这个结构中,变量名是循环中使用的变量,取值列表是一系列的值,这些值在每次循环迭代时会依次赋给变量名。命令序列则是每次循环需要执行的一系列命令。


for循环的工作原理

  for循环的工作流程是这样的:首先,它会从取值列表中取出第一个值,赋给变量名,然后执行do和done之间的命令序列。完成后,循环会继续取下一个值,并重复这个过程,直到取值列表中的所有值都被使用过。

Shell 编程之循环语句与函数、数组_数组

实际应用案例分析

批量添加与删除用户

  在系统管理中,我们可能需要批量创建或删除用户账户。使用for循环,我们可以轻松地实现这一任务。例如,以下脚本可以用来批量创建用户:

for user in user1 user2 user3
do
    userdel $user
    echo "User $user deleted successfully."
done

同样地,我们也可以使用for循环来批量删除用户:

for user in user1 user2 user3
do
    userdel $user
    echo "User $user deleted successfully."
done

检查主机状态

  如果我们需要检查一系列主机是否在线,for循环同样可以派上用场。以下是一个简单的脚本,用于检查主机列表中每个主机的状态:

for host in   
do
    ping -c 1 $host && echo "$host is up" || echo "$host is down"
done

while循环语句

  while循环是Shell编程中另一种重要的循环控制结构,它允许在给定条件为真时重复执行一组命令。与for循环相比,while循环更适合处理那些未知迭代次数的情况。

Shell 编程之循环语句与函数、数组_学习笔记_02

其基本语法如下:

while [ 条件判断表达式 ]
do
    命令序列
done

while循环的工作原理

  while循环的执行流程是这样的:首先,它会评估条件判断表达式,如果表达式结果为真(即返回状态为0),则执行do和done之间的命令序列。完成后,循环会再次评估条件表达式,如果仍为真,则继续执行命令序列。这个过程会一直重复,直到条件表达式为假(即返回状态非0)为止。

实际应用案例分析

批量添加规律编号的用户

  假设我们需要创建一系列编号连续的用户,例如user1到user100,可以使用while循环来实现:

count=1
while [ $count -le 100 ]
do
    useradd user$count
    echo "User user$count added successfully."
    ((count++))
done
猜价格游戏
#!/bin/bash
jiage=$(expr $RANDOM % 1000)
cichu=0
echo "猜价格"
while true
do
    read -p "输入价格" cdjiage
    let cishu++
  if
    [ $cdjiage -eq $jiage ]
    then
        echo "猜对了"
        echo "猜了$cishu次"
        exit 0
  elif
      [ $cdjiage -gt $jiage ]
       then
            echo "大了"
  else
       echo "小了"
  fi
done

until 循环语句

until 语句的结构

  until循环是Shell编程中的一种循环控制结构,它与while循环相反,until循环会在给定的条件为假时执行循环体内的命令序列,直到条件为真时停止。

Shell 编程之循环语句与函数、数组_数组_03

其基本语法结构如下:

until 条件测试操作
do
    命令序列
done

until循环的工作原理

  until循环的执行流程是这样的:首先判断until后的条件测试操作结果,如果条件不成立(即返回状态非0),则执行do和done之间的命令序列。完成后,循环会再次判断条件测试结果,如果条件仍然不成立,则继续执行命令序列。这个过程会一直重复,直到条件测试结果成立(即返回状态为0)为止,然后跳转到done语句,结束循环。

until语法案例

案例一:累加求和
#!/bin/bash
i=0; s=0
until [ $i -eq 50 ]
do
    let "i=$i+1"; let "s=$s+$i"
done
echo 'sum(1..50)='$s

当执行此脚本时,它会输出1到50的累加求和结果。

案例二:递减输出
#!/bin/bash
var1=100
until [ $var1 -eq 0 ]
do
    echo $var1
    var1=$[ $var1 - 25 ]
done

执行这个脚本会依次输出100, 75, 50, 25, 0。

  通过这些案例,我们可以看到until循环在Shell编程中的应用,特别是在需要反复执行一组命令直到某个条件成立时非常有用。

Shell函数

  Shell函数是一种将命令集封装起来以便重复使用的结构。在Shell脚本执行过程中,函数被加载到内存中,这意味着每次调用函数时,都无需从硬盘读取,从而提高了运行速度。虽然在Shell编程中函数不是必需的,但它们可以使程序更加有组织,提高代码的可读性和可重用性,同时避免重复编写大量代码。

函数的用法

函数的基本语法如下:

[function] 函数名() {
    命令序列
    [return x]
}
  • function关键字用于定义一个函数,这个关键字是可选的。
  • { 符号标志着函数命令的开始,可以与函数名位于同一行,也可以位于下一行的开头。
  • } 符号标志着函数体的结束,{}之间的部分是函数体。
  • 函数体内可以包含任意的Shell命令,也可以调用其他函数。
  • return用于从函数返回一个值,可以用来判断执行是否成功。也可以使用exit来终止整个Shell脚本。

案例

一个简单的函数脚本

以下是一个简单的Shell脚本,其中定义了两个函数:

#!/bin/bash
zhangsan() {
    echo "my name is zhangsan"
}

lisi() {
    echo "my name is lisi"
}

zhangsan
lisi

执行这个脚本会依次输出两个函数中定义的字符串。

带有参数的shell函数示例

Shell函数还可以接受参数。以下是一个带参数的函数示例:

#!/bin/bash
name() {
    echo "my name is $1"
}

name $1

执行这个脚本并传递一个参数,如zhangsan,会输出my name is zhangsan。

函数变量的作用范围

函数中的变量可以是局部的,也可以是全局的。以下是一个演示函数变量作用范围的脚本:

#!/bin/bash
myfun() {
    local i
    i=8
    echo $i
}

i=9
myfun
echo $i

在这个脚本中,函数myfun内部定义了一个局部变量i,它的改变不会影响到函数外部的变量i。

案例 - 递归函数

#!/bin/bash
function factorial {
    if [ $1 -eq 1 ]
    then
        echo 1
    else
        local temp=$[ $1 - 1 ]
        local result=$(factorial $temp)
        echo $[ $result * $1 ]
    fi
}

read -p "Enter value: " value
result=$(factorial $value)
echo "The factorial of $value is: $result"

当运行这个脚本并输入一个值时,它会计算并输出该值的阶乘。

Shell数组

  在Shell脚本中,数组是一种常见的数据结构,它的主要应用场景包括获取数组长度、获取元素长度、遍历元素、元素切片、元素替换、元素删除等。与其他编程语言如Java、C、Python不同,Shell中只有一维数组,没有多维数组。

定义数组的方法

Shell中定义数组有多种方法,以下是几种常用的定义方式:

方法一:

数组名=(value0 value1 value2 ...)

方法二:

数组名=([0]=value [1]=value [2]=value ...)

方法三:

列表名="value0 value1 value2 ..."
数组名=($列表名)

方法四:

数组名[0]="value"
数组名[1]="value"
数组名[2]="value"

获取数组长度

获取数组长度的方法如下:

arr_number=(1 2 3 4 5)
arr_length=${#arr_number[*]}
echo $arr_length  # 输出 5
arr_length_1=${#arr_number[@]}
echo $arr_length_1  # 输出 5

读取某下标赋值

读取特定下标的数组元素值的方法如下:

arr_index2=${arr_number[2]}  # 读取第三个元素
echo $arr_index2  # 输出 3

数组遍历

遍历数组的方法如下:

arr_number=(1 2 3 4 5)
for v in ${arr_number[@]}
do
    echo $v
done
# 输出 1 2 3 4 5

数组切片

数组切片的方法如下:

arr=(1 2 3 4 5)
echo ${arr[@]}  # 输出整个数组 1 2 3 4 5
echo ${arr[@]:0:2}  # 输出数组的前两个元素 1 2
echo ${arr[@]:2:3}  # 输出从第三个元素开始的三个元素 3 4 5

数组替换

数组元素替换的方法如下:

rr=(1 2 3 4 5)
echo ${arr[@]/4/66}  # 输出 1 2 3 66 5,但不会替换数组原有内容
arr=(${arr[@]/4/66})  # 要实现改变原有数组,可通过重新赋值实现
echo ${arr[@]}  # 输出 1 2 3 66 5

数组删除

删除数组或数组元素的方法如下:

arr=(1 2 3 4 5)
unset arr  # 删除整个数组
echo ${arr[*]}  # 不会有输出
arr=(1 2 3 4 5)
unset arr[2]  # 删除数组的第三个元素
echo ${arr[*]}  # 输出 1 2 4 5

总结

  在本文中,我们详细探讨了Shell编程中的循环语句和函数的使用方法。通过具体的示例和案例分析,我们了解了如何有效地使用forwhileuntil循环来处理重复任务,并且学习了如何定义和使用Shell函数来提高代码的模块化和可重用性。

  通过for循环,我们可以轻松地实现批量操作,例如批量添加或删除用户,以及检查一系列主机的状态。while循环则在处理不确定迭代次数的任务时表现出了其灵活性,例如创建一系列编号连续的用户或编写猜价格游戏。until循环则在条件不成立时执行命令序列,直到条件满足后才会停止循环,这在某些场景下非常有用。

  函数在Shell编程中的作用不可小觑。它们不仅可以使脚本更加有组织,还可以提高程序的可读性和重用性。我们学习了如何定义函数、如何向函数传递参数、函数变量的作用范围,以及如何实现递归函数。

  此外,我们还探讨了Shell数组的定义和操作,包括获取数组长度、数组遍历、数组切片、数组替换和数组删除等操作,这些都是Shell脚本中常用的数据操作。