【Shell进阶】循环控制与函数编程

Shell循环与函数编程精要

while

基本语法

while [ condition ]
do
    commands
done

或者:

while condition; do
    commands
done

基本示例

简单计数循环

#!/bin/bash

# 从1数到5
count=1
while [ $count -le 5 ]
do
    echo "计数: $count"
    count=$((count + 1))
done

无限循环

使用 true 命令

#!/bin/bash

# 无限循环,需要 break 退出
count=0
while true
do
    echo "循环次数: $count"
    ((count++))
    
    if [ $count -ge 5 ]; then
        echo "达到5次,退出循环"
        break
    fi
    
    sleep 1
done

示例2:菜单系统

#!/bin/bash

show_menu() {
    while true
    do
        echo "=== 系统菜单 ==="
        echo "1. 显示系统信息"
        echo "2. 显示磁盘使用"
        echo "3. 显示内存使用"
        echo "4. 退出"
        
        read -p "请选择 [1-4]: " choice
        
        case $choice in
            1)
                echo "系统信息:"
                uname -a
                ;;
            2)
                echo "磁盘使用:"
                df -h
                ;;
            3)
                echo "内存使用:"
                free -h
                ;;
            4)
                echo "再见!"
                break
                ;;
            *)
                echo "无效选择,请重新输入"
                ;;
        esac
        
        echo
        read -p "按回车键继续..."
        clear
    done
}

show_menu

函数

函数定义

​ 函数是一种将一组命令封装起来的方式,可以多次调用。

​ 函数可以接受参数,并返回退出状态码(0表示成功,非0表示失败)。

基本语法

# 方式1
function_name() {
    commands
}


# 方式2(使用function关键字)
function function_name() {
    commands
}

示例

#!/bin/bash

# 定义函数
say_hello() {
    echo "Hello, World!"
}

# 调用函数
say_hello

函数参数

传递参数

函数内部使用位置参数($1, $2, …)来获取传递的参数。

bash

#!/bin/bash

greet() {
    local name=$1
    local greeting=${2:-"Hello"}  # 默认值
    echo "$greeting, $name!"
}

# 调用函数
greet "Alice"
greet "Bob" "Good morning"

特殊参数

  • $#:传递的参数个数
  • $@:所有参数(每个参数作为独立的字符串)
  • $*:所有参数(作为一个字符串)
  • $0:函数名(在函数内部,实际上仍然是脚本名)
  • $1, $2, ...:第1个、第2个参数等
#!/bin/bash

show_args() {
    echo "参数个数: $#"
    echo "所有参数: $@"
    echo "第一个参数: $1"
    echo "第二个参数: $2"
}

show_args "arg1" "arg2" "arg3"

返回值

退出状态码

函数返回最后一条命令的退出状态码,也可以使用 return 命令指定。

bash

#!/bin/bash

is_even() {
    local number=$1
    if [ $((number % 2)) -eq 0 ]; then
        return 0  # 成功,表示是偶数
    else
        return 1  # 失败,表示不是偶数
    fi
}

# 调用函数
if is_even 4; then
    echo "4 是偶数"
else
    echo "4 是奇数"
fi

返回数据

函数可以通过标准输出返回数据,使用命令替换捕获。

bash

#!/bin/bash

get_today() {
    date +%Y-%m-%d
}

# 调用函数并捕获输出
today=$(get_today)
echo "今天是: $today"

数组

定义数组

# 方法1:直接赋值
array=("apple" "banana" "cherry" "date")

# 方法2:逐个元素赋值
array[0]="apple"
array[1]="banana"
array[2]="cherry"
array[3]="date"

# 方法3:包含空格的元素,使用引号
array=("red apple" "yellow banana" "red cherry")

# 方法4:从命令输出创建
files=($(ls *.txt))   # 注意:如果文件名有空格,这种方法会出问题

访问数组元素

# 访问单个元素
echo "${array[0]}"    # 第一个元素:apple
echo "${array[1]}"    # 第二个元素:banana
echo "${array[-1]}"   # 最后一个元素:date
echo "${array[-2]}"   # 倒数第二个元素:cherry

# 访问所有元素
echo "${array[@]}"    # 所有元素作为独立单词
echo "${array[*]}"    # 所有元素作为单个字符串

数组信息

# 数组长度
echo "数组长度: ${#array[@]}"

# 元素长度
echo "第一个元素长度: ${#array[0]}"

# 所有索引
echo "所有索引: ${!array[@]}"

数组遍历

遍历元素

#!/bin/bash

fruits=("apple" "banana" "cherry" "date")

# 方法1:直接遍历元素
echo "方法1 - 直接遍历:"
for fruit in "${fruits[@]}"; do
    echo "水果: $fruit"
done

# 方法2:通过索引遍历
echo -e "\n方法2 - 索引遍历:"
for i in "${!fruits[@]}"; do
    echo "索引 $i: ${fruits[i]}"
done

# 方法3:C风格循环
echo -e "\n方法3 - C风格循环:"
for ((i=0; i<${#fruits[@]}; i++)); do
    echo "元素 $i: ${fruits[i]}"
done

数组操作

添加元素

#!/bin/bash

array=("apple" "banana")

# 方法1:添加到末尾
array+=("cherry")
array+=("date" "elderberry")

# 方法2:指定索引
array[5]="fig"  # 注意:索引4会是空值

# 方法3:插入到开头(复杂)
array=("orange" "${array[@]}")

echo "数组内容: ${array[@]}"
echo "数组索引: ${!array[@]}"

删除元素

#!/bin/bash

array=("apple" "banana" "cherry" "date")

# 删除第二个元素
unset array[1]

# 删除整个数组
# unset array

echo "删除后数组: ${array[@]}"
echo "剩余索引: ${!array[@]}"

数组切片

#!/bin/bash

array=("apple" "banana" "cherry" "date" "elderberry" "fig")

# 切片操作
echo "前三个: ${array[@]:0:3}"
echo "从第二个开始的两个: ${array[@]:1:2}"
echo "最后两个: ${array[@]: -2}"
echo "从第二个到结尾: ${array[@]:2}"
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值