Bootstrap

shell编程(8)

目录

一、until循环

示例

until 和 while 的区别

二、case语句

基本语法

示例

1. 简单的 case 语句

2. 使用通配符

3. 处理多个匹配

case 和 if 的比较

case 语句:

if 语句:

三、基本函数

基本函数定义和调用

1. 定义一个简单的函数

2. 函数接收参数

3. 返回值

4. 使用 return 返回状态码

5. 局部变量和全局变量

6. 函数的递归调用

7. 函数中的错误处理

8. 函数的默认参数


声明:学习视频来自b站up主 泷羽sec,如涉及侵权马上删除文章

声明:本文主要用作技术分享,所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险,并遵循相关法律法规。

一、until循环

在Shell编程中,until 时执行循环体。

bash复制代码until [ 条件 ]
do
    
    
# 循环体
​
d
done
​
``

until 循环会

示例

  1. 基本例子: 打印数字count 达到 5。

bash复制代码count=1
until [ $count -gt 5 ]
do
    echo $count
    ((count++))
​
    ((co
​
    (
​
  
done

解释

  • 循环开始时,count 的值为 1。

  • 条件是 count -gt 5,即 count 是否大于 5。当 count 小于或等于 5 时,循环体继续执行。

  • 每次循环后,count 会增加 1。

输出结果:

复制代码1
2
3
4
5
  1. 判断文件是否存在:直到文件存在时退出。

bash复制代码until [ -f /path/to/file ]
do
    echo "文件还不存在,等待中..."
    sleep 2
done
echo "文件已存在,继续执行"

解释

  • 每隔 2 秒检查一次文件是否存在,直到文件存在时,退出循环。

untilwhile 的区别

  • until 循环是当条件为假时才执行,而 while 循环是当条件为真时才执行。

例如:

bash复制代码# while 例子:当条件为真时执行
while [ $count -lt 5 ]
do
    echo $count
    ((count++))
done
​
# until 例子:当条件为假时执行
count=1
until [ $count -gt 5 ]
do
    echo $count
    ((count++))
done

二、case语句

基本语法

bash复制代码case 变量 in
    pattern1)
        # 当变量匹配 pattern1 时执行的命令
        ;;
    pattern2)
        # 当变量匹配 pattern2 时执行的命令
        ;;
    *)
        # 默认情况,如果变量不匹配任何模式时执行的命令
        ;;
esac
  • 变量 是你要检查的变量。

  • pattern1, pattern2 等是模式,可以是文字、通配符(例如 *)或正则表达式。

  • ;; 用于结束每个匹配的执行块。

  • * 是一个通配符,表示所有其他没有匹配的情况,相当于 default

示例

1. 简单的 case 语句
bash复制代码echo "请输入一个数字:"
read num
​
case $num in
    1)
        echo "你输入的是数字 1"
        ;;
    2)
        echo "你输入的是数字 2"
        ;;
    3)
        echo "你输入的是数字 3"
        ;;
    *)
        echo "你输入的不是 1, 2 或 3"
        ;;
esac

解释

  • 程序提示用户输入一个数字,然后根据输入的值匹配不同的模式。

  • 如果输入的是 1,2 或 3,程序会分别输出相应的信息;否则输出默认信息。

2. 使用通配符
bash复制代码echo "请输入一个文件名:"
read filename
​
case $filename in
    *.txt)
        echo "这是一个文本文件"
        ;;
    *.jpg | *.png)
        echo "这是一个图片文件"
        ;;
    *)
        echo "无法识别的文件类型"
        ;;
esac

解释

  • 这个示例中,case 语句根据文件名的扩展名来判断文件类型。

  • 如果文件名以 .txt 结尾,输出“这是一个文本文件”;如果是 .jpg.png,则输出“这是一个图片文件”;其他文件类型则输出“无法识别的文件类型”。

3. 处理多个匹配
bash复制代码echo "请输入一个字符:"
read char
​
case $char in
    [a-z])
        echo "你输入的是一个小写字母"
        ;;
    [A-Z])
        echo "你输入的是一个大写字母"
        ;;
    [0-9])
        echo "你输入的是一个数字"
        ;;
    *)
        echo "你输入的不是字母或数字"
        ;;
esac

解释

  • case 语句根据用户输入的字符进行分类。

  • [a-z] 匹配小写字母,[A-Z] 匹配大写字母,[0-9] 匹配数字。

caseif 的比较

case 语句的优势在于它能简洁地处理多种条件,而 if 语句通常用于两种条件或逻辑较为复杂的情况。对于多重条件判断,case 语句通常更加清晰和简洁。

例如,以下两种写法是等价的:

case 语句:
bash复制代码case $color in
    red)
        echo "红色"
        ;;
    blue)
        echo "蓝色"
        ;;
    green)
        echo "绿色"
        ;;
    *)
        echo "未知颜色"
        ;;
esac
if 语句:
bash复制代码if [ "$color" = "red" ]; then
    echo "红色"
elif [ "$color" = "blue" ]; then
    echo "蓝色"
elif [ "$color" = "green" ]; then
    echo "绿色"
else
    echo "未知颜色"
fi

三、基本函数

基本函数定义和调用

在 Shell 中,函数的基本语法如下:

bash复制代码function 函数名 {
    # 函数体
    # 这里放你希望执行的命令
}
​
# 或者简化版本
函数名() {
    # 函数体
}

1. 定义一个简单的函数

bash复制代码my_function() {
    echo "Hello, World!"
}
​
# 调用函数
my_function

解释

  • my_function 是函数名,函数体中只有一个 echo 命令用于输出 "Hello, World!"。

  • 调用时,只需写出函数名 my_function 即可执行该函数。

2. 函数接收参数

函数可以通过 $1, $2, $3, 等来接收参数,表示调用时传入的值。

bash复制代码greet() {
    echo "Hello, $1!"
}
​
greet "Alice"  # 输出:Hello, Alice!
greet "Bob"    # 输出:Hello, Bob!

解释

  • 函数 greet 接收一个参数 $1,并将其用于输出欢迎信息。

  • 你可以在函数调用时传递参数,$1 就是第一个传入的值。

3. 返回值

在 Shell 函数中,并不像其他编程语言那样直接通过 return 返回值,return 通常用于返回一个状态码(0 表示成功,非0 表示失败)。如果需要返回实际值,可以通过 echo 来实现。

bash复制代码add_numbers() {
    local sum=$(( $1 + $2 ))  # local 用于局部变量
    echo $sum
}
​
result=$(add_numbers 5 3)  # 调用函数并将返回值赋给变量
echo "Result: $result"      # 输出:Result: 8

解释

  • add_numbers 函数接收两个参数并计算它们的和。

  • echo 输出和,通过 $(...) 语法将其捕获并赋值给 result 变量。

4. 使用 return 返回状态码

return 语句用于返回一个状态码(通常是 0 或非零的整数),可以用来表示函数执行的成功或失败。

bash复制代码check_number() {
    if [ $1 -lt 0 ]; then
        return 1  # 返回非0,表示失败
    else
        return 0  # 返回0,表示成功
    fi
}
​
check_number -5
if [ $? -eq 0 ]; then
    echo "输入的是一个非负数"
else
    echo "输入的是一个负数"
fi

解释

  • check_number 函数检查传入的数字是否为负数。

  • 使用 return 返回一个状态码,$? 用于检查函数的返回值。如果是 0,表示函数执行成功;如果是非 0,表示失败。

5. 局部变量和全局变量

在 Shell 中,变量默认是全局的,可以在函数外部访问。在函数内部,若希望定义局部变量,可以使用 local 关键字。

bash复制代码function test_vars() {
    local var1="local variable"  # 局部变量
    var2="global variable"       # 全局变量
    echo "Inside function: $var1"
    echo "Inside function: $var2"
}
​
var2="This is global"
​
test_vars
echo "Outside function: $var2"  # 输出全局变量

解释

  • local 关键字用于定义局部变量 var1,该变量仅在函数内部有效。

  • var2 是全局变量,可以在函数外部访问。

6. 函数的递归调用

Shell 函数支持递归调用,即函数在其内部调用自己。注意要有结束条件,以避免无限递归。

bash复制代码factorial() {
    if [ $1 -le 1 ]; then
        echo 1
    else
        local result=$(( $1 * $(factorial $(( $1 - 1 ))) ))
        echo $result
    fi
}
​
result=$(factorial 5)
echo "5的阶乘是:$result"  # 输出:5的阶乘是:120

解释

  • factorial 函数计算一个数字的阶乘。

  • 当输入小于或等于 1 时,返回 1;否则,递归调用自己并计算阶乘。

7. 函数中的错误处理

在函数中进行错误处理时,可以通过检查命令的退出状态码或使用 set -e 来中止脚本。

bash复制代码divide() {
    if [ $2 -eq 0 ]; then
        echo "Error: Division by zero is not allowed!"
        return 1  # 返回错误码
    fi
    local result=$(( $1 / $2 ))
    echo $result
}
​
result=$(divide 10 0)
if [ $? -ne 0 ]; then
    echo "发生错误,不能除以零"
else
    echo "结果是:$result"
fi

解释

  • divide 函数检查是否发生了除零错误。

  • 如果第二个参数为 0,则返回错误码并输出错误信息。

8. 函数的默认参数

Shell 函数也可以设置默认参数,以防用户没有提供值。

bash复制代码greet() {
    local name="${1:-World}"  # 如果没有传递参数,则默认值为 "World"
    echo "Hello, $name!"
}

greet "Alice"  # 输出:Hello, Alice!
greet          # 输出:Hello, World!

;