Shell学习(5/6) 流程控制-函数

九、流程控制

Shell 脚本支持常见的流程控制结构,如条件判断、循环和分支选择。

1. 条件判断

条件判断用于根据条件执行不同的代码块。Shell 中最常用的条件判断语句是 if

1.1 if 语句

基本语法
shell 复制代码
if [ 条件 ]; then
    # 条件为真时执行的代码
elif [ 其他条件 ]; then
    # 其他条件为真时执行的代码
else
    # 所有条件为假时执行的代码
fi

注意sh 的流程控制不可为空,如果 else 分支没有语句执行,就不要写这个 else

示例
shell 复制代码
#!/bin/bash

age=18

if [ "$age" -lt 18 ]; then
    echo "未成年"
elif [ "$age" -eq 18 ]; then
    echo "刚成年"
else
    echo "成年"
fi
条件表达式
  • 数值比较
    • -eq:等于
    • -ne:不等于
    • -gt:大于
    • -ge:大于等于
    • -lt:小于
    • -le:小于等于
  • 字符串比较
    • =:等于
    • !=:不等于
    • -z:字符串长度为 0
    • -n:字符串长度不为 0
  • 文件测试
    • -e:文件存在
    • -f:是普通文件
    • -d:是目录
    • -r:文件可读
    • -w:文件可写
    • -x:文件可执行

1.2 case 语句

case 语句用于多分支选择,类似于其他语言中的 switch

基本语法
shell 复制代码
case 变量 in
    模式1)
        # 匹配模式1时执行的代码
        ;;
    模式2)
        # 匹配模式2时执行的代码
        ;;
    *)
        # 默认情况
        ;;
esac
示例
shell 复制代码
#!/bin/bash

fruit="apple"

case "$fruit" in
    "apple")
        echo "这是苹果"
        ;;
    "banana")
        echo "这是香蕉"
        ;;
    *)
        echo "未知水果"
        ;;
esac

2. 循环

循环用于重复执行一段代码,直到满足某个条件。Shell 支持 forwhileuntil 循环。

2.1 for 循环

基本语法
shell 复制代码
for 变量 in 列表; do
    # 循环体
done
示例
shell 复制代码
#!/bin/bash

for i in 1 2 3 4 5; do
    echo "当前值: $i"
done
遍历文件
shell 复制代码
for file in *.txt; do
    echo "处理文件: $file"
done

当前目录下有一个 test.txt


2.2 while 循环

while 循环在条件为真时重复执行代码。

基本语法
shell 复制代码
while [ 条件 ]; do
    # 循环体
done
示例
shell 复制代码
#!/bin/bash

count=0

while [ "$count" -lt 5 ]; do
    echo "当前计数: $count"
    count=$((count + 1))
done
  • $(( )) 是进行算术运算时的正确语法。
  • $() 是用来执行命令替换,获取命令输出的结果。

2.3 until 循环

until 循环在条件为假时重复执行代码,直到条件为真。

基本语法
shell 复制代码
until [ 条件 ]; do
    # 循环体
done
示例
shell 复制代码
#!/bin/bash

count=0

until [ "$count" -ge 4 ]; do
    echo "当前计数: $count"
    count=$((count + 1))
done

2.4 循环控制

  • break:退出循环。
  • continue:跳过当前迭代,进入下一次循环。
示例
shell 复制代码
#!/bin/bash

for i in {1..10}; do
    if [ "$i" -eq 5 ]; then
        break  # 退出循环
    fi
    echo "当前值: $i"
done

十、函数

在 Shell 脚本中,函数是一种将代码封装为可重用块的方式。

1. 函数的定义

Shell 函数的定义有两种方式:

1.1 使用 function 关键字

shell 复制代码
function 函数名 {
    # 函数体
}

1.2 使用 () 定义

shell 复制代码
函数名() {
    # 函数体
}
示例
shell 复制代码
# 方式 1
function greet {
    echo "Hello, World!"
}

# 方式 2
greet() {
    echo "Hello, World!"
}

2. 函数的调用

定义函数后,可以通过函数名直接调用。

示例
shell 复制代码
greet() {
    echo "Hello, World!"
}

# 调用函数
greet

3. 函数的参数

Shell 函数可以接收参数。在函数内部,通过 $1$2$3 等访问参数。

  • $1:第一个参数
  • $2:第二个参数
  • $#:参数个数
  • $@:所有参数列表
  • $*:所有参数作为一个字符串
示例
shell 复制代码
greet() {
    echo "Hello, $1!"
}

# 调用函数并传递参数
greet "Alice"
greet "Bob"

4. 函数的返回值

Shell 函数可以通过 return 返回一个整数值(0-255),或者通过 echo 返回字符串。

4.1 使用 return 返回值

  • return 只能返回整数值。
  • 调用函数后,通过 $? 获取返回值。
示例
shell 复制代码
add() {
    local sum=$(( $1 + $2 ))
    return $sum
}

add 3 5
echo "结果是: $?"

4.2 使用 echo 返回值

  • echo 可以返回字符串或任意值。
  • 调用函数后,通过 $(函数名) 捕获返回值。

5. 局部变量

在函数内部定义的变量默认是全局的。如果希望变量只在函数内部使用,可以使用 local 关键字定义局部变量。

示例
shell 复制代码
greet() {
    local name="Alice"
    echo "Hello, $name!"
}

greet
echo "Name outside function: $name"  # 这里 $name 为空

6. 函数的嵌套

Shell 函数可以嵌套调用,即在一个函数内部调用另一个函数。

示例
shell 复制代码
greet() {
    echo "Hello, $1!"
}

introduce() {
    greet "$1"
    echo "I am a Shell script."
}

introduce "Alice"

7. 递归函数

Shell 函数支持递归调用,即函数调用自身。

示例:计算阶乘
shell 复制代码
factorial() {
    if [ "$1" -le 1 ]; then
        echo 1
    else
        local prev=$(factorial $(( $1 - 1 )))
        echo $(( $1 * prev ))
    fi
}

result=$(factorial 5)
echo "5 的阶乘是: $result"

8. 函数的返回值与状态码

  • 函数默认返回最后一条命令的退出状态码。
  • 可以通过 return 显式返回状态码(0 表示成功,非 0 表示失败)。
示例
shell 复制代码
check_file() {
    if [ -f "$1" ]; then
        echo "文件 $1 存在"
        return 0
    else
        echo "文件 $1 不存在"
        return 1
    fi
}

check_file "test.txt"
if [ "$?" -eq 0 ]; then
    echo "文件检查成功"
else
    echo "文件检查失败"
fi
相关推荐
爱吃猫的鱼ouou6 分钟前
解决Ubuntu20.04重启出现显卡驱动异常的问题(操作记录)
服务器·ubuntu
SunTecTec10 分钟前
Linux 在个人家目录下添加环境变量 如FLINK_PROPERTIES=“jobmanager.rpc.address: jobmanager“
linux·运维·服务器
davysiao12 分钟前
CentOS 使用国内镜像安装 nvm 和 Node.js 完整指南
linux·centos·node.js
杨凯凡16 分钟前
Linux性能大师:htop与nmon实战对比分析
linux·运维·服务器
OpenLoong 开源社区35 分钟前
技术视界 | 数据的金字塔:从仿真到现实,机器人学习的破局之道
人工智能·学习·机器人·开源社区·人形机器人·openloong
MXsoft61836 分钟前
监控易一体化运维:巧用排班管理,提升运维协同效能
大数据·服务器·数据库
B64A-消闲43 分钟前
case和字符串操作
linux·运维·服务器
码农研究僧1 小时前
Ubuntu 磁盘空间占用清理(宝塔)
linux·运维·ubuntu
{⌐■_■}1 小时前
【计网】认识跨域,及其在go中通过注册CORS中间件解决跨域方案,go-zero、gin
java·linux·开发语言·c++·中间件·golang·gin
若疆赤云online1 小时前
window和ubuntu自签证书
linux·运维·ubuntu