Shell编程之函数与数组
格式1:标准写法bash函数名() {命令序列[return 返回值]格式2:使用function关键字bashfunction 函数名 {命令序列[return 返回值]函数调用自身称为递归,必须有一个终止条件。
·
一、Shell函数
1. 函数的定义与调用
函数定义格式
格式1:标准写法
函数名() {
命令序列
[return 返回值]
}
格式2:使用function关键字
bash
function 函数名 {
命令序列
[return 返回值]
}
函数调用
# 直接调用 函数名 # 带参数调用 函数名 参数1 参数2
示例1:基础函数
#!/bin/bash
# 定义简单函数
hello() {
echo "Hello, World!"
}
# 调用函数
hello
示例2:带返回值的函数
#!/bin/bash
# 计算两个数的和
add() {
local sum=$(( $1 + $2 ))
echo $sum
return 0
}
# 调用函数并获取返回值
result=$(add 10 20)
echo "两数之和为: $result"
2. 函数变量的作用范围
全局变量与局部变量
#!/bin/bash
# 演示变量作用范围
# 全局变量
global_var="我是全局变量"
test_scope() {
# 局部变量
local local_var="我是局部变量"
echo "函数内部:"
echo " - global_var = $global_var" # 可以访问全局变量
echo " - local_var = $local_var" # 可以访问局部变量
# 修改全局变量
global_var="全局变量被函数修改"
}
# 调用函数
test_scope
echo "函数外部:"
echo " - global_var = $global_var" # 全局变量已被修改
echo " - local_var = $local_var" # 无法访问局部变量(输出为空)
示例:变量作用域实战
#!/bin/bash
# 计算器程序
result=0 # 全局变量
add() {
local a=$1
local b=$2
result=$((a + b)) # 修改全局变量
echo "加法结果(内部): $result"
}
subtract() {
local a=$1
local b=$2
local result=$((a - b)) # 局部变量,不影响全局
echo "减法结果(内部): $result"
}
add 20 30
echo "加法结果(外部): $result" # 输出50
subtract 50 30
echo "减法结果(外部): $result" # 仍然是50,未被修改
3. 函数的参数
参数处理特殊变量
| 变量 | 说明 |
|---|---|
$0 |
脚本名称 |
$1、$2... |
第1个、第2个...参数 |
$# |
参数个数 |
$* |
所有参数(作为一个字符串) |
$@ |
所有参数(作为多个字符串) |
$? |
上一个命令的退出状态 |
示例1:基础参数传递
#!/bin/bash
# 显示函数参数
show_params() {
echo "函数名称: $0"
echo "第一个参数: $1"
echo "第二个参数: $2"
echo "第三个参数: $3"
echo "参数总数: $#"
echo "所有参数(\$*): $*"
echo "所有参数(\$@): $@"
}
show_params apple banana orange
示例2:参数遍历
#!/bin/bash
# 计算多个数的平均值
average() {
local sum=0
local count=$#
# 使用$@遍历所有参数
for num in $@
do
sum=$((sum + num))
done
echo "总和: $sum"
echo "个数: $count"
echo "平均值: $((sum / count))"
}
average 10 20 30 40 50
示例3:带选项的函数
#!/bin/bash
# 带选项的日志函数
log_message() {
local level="INFO" # 默认级别
local message=""
# 解析选项
while getopts "l:m:" opt
do
case $opt in
l) level="$OPTARG" ;;
m) message="$OPTARG" ;;
*) echo "用法: $0 -l [级别] -m [消息]" ;;
esac
done
echo "[$(date '+%Y-%m-%d %H:%M:%S')] [$level] $message"
}
# 调用函数
log_message -l "ERROR" -m "文件未找到"
log_message -l "WARNING" -m "磁盘空间不足"
log_message -m "这是一条INFO日志" # 使用默认级别
示例4:参数默认值
#!/bin/bash
# 设置默认参数
create_user() {
local username=${1:-guest} # 如果没有参数,默认为guest
local home_dir=${2:-/home/$username}
local shell=${3:-/bin/bash}
echo "创建用户:"
echo " 用户名: $username"
echo " 家目录: $home_dir"
echo " Shell: $shell"
}
create_user alice
echo "---"
create_user bob /home/bob123 /bin/zsh
4. 递归函数
什么是递归函数?
函数调用自身称为递归,必须有一个终止条件。
示例1:计算阶乘
#!/bin/bash
# 递归计算阶乘
factorial() {
local num=$1
# 终止条件
if [ $num -le 1 ]; then
echo 1
return 0
fi
# 递归调用
local prev=$(factorial $((num - 1)))
echo $((num * prev))
}
# 测试
result=$(factorial 5)
echo "5的阶乘是: $result" # 输出120
示例2:斐波那契数列
#!/bin/bash
# 递归计算斐波那契数列
fibonacci() {
local n=$1
if [ $n -le 1 ]; then
echo $n
return 0
fi
local prev1=$(fibonacci $((n - 1)))
local prev2=$(fibonacci $((n - 2)))
echo $((prev1 + prev2))
}
echo "斐波那契数列第10项: $(fibonacci 10)"
示例3:递归遍历目录
#!/bin/bash
# 递归遍历目录并计算文件数量
count_files() {
local dir=$1
local count=0
echo "进入目录: $dir"
# 遍历目录中的每个文件/子目录
for item in "$dir"/*
do
if [ -f "$item" ]; then
# 是普通文件
count=$((count + 1))
echo " 文件: $item"
elif [ -d "$item" ]; then
# 是子目录,递归调用
local sub_count=$(count_files "$item")
count=$((count + sub_count))
fi
done
echo "目录 $dir 包含 $count 个文件"
return $count
}
# 调用函数(需要指定实际存在的目录)
count_files "/etc"
示例4:递归创建目录结构
#!/bin/bash
# 递归创建嵌套目录
create_nested_dirs() {
local path=$1
local depth=$2
# 终止条件
if [ $depth -le 0 ]; then
return
fi
# 创建当前目录
mkdir -p "$path"
echo "创建目录: $path"
# 递归创建子目录
create_nested_dirs "$path/level$depth" $((depth - 1))
}
create_nested_dirs "./test_tree" 3
tree ./test_tree # ;需要tree命令的方式
local parth-ilem
更多推荐


所有评论(0)