Shell 脚本函数:function 与参数
Shell 函数用于将一段重复使用的代码块封装起来,以便在脚本中多次调用,从而减少代码冗余并提高可维护性。
定义函数
使用以下两种语法定义一个函数。
选择第一种语法(更常用且兼容 POSIX 标准):
function_name() {
# 代码块
commands
}
选择第二种语法(Bash 特有):
function function_name {
# 代码块
commands
}
创建文件 test_func.sh 并输入以下代码:
check_disk() {
echo "正在检查磁盘空间..."
df -h
}
调用函数
编写函数定义后,在脚本中直接使用函数名即可调用。
添加调用代码:
#!/bin/bash
check_disk() {
echo "正在检查磁盘空间..."
df -h
}
# 调用函数
check_disk
赋予执行权限并运行:
chmod +x test_func.sh
./test_func.sh
传递参数
函数可以像脚本一样接收参数。在函数内部,使用位置变量来读取这些参数。
修改 check_disk 函数以接收一个参数(挂载点):
check_disk() {
echo "正在检查 $1 的磁盘空间..."
df -h | grep "$1"
}
调用函数并传递参数:
check_disk "/dev/sda1"
这里 $1` 在函数内部代表函数接收的第一个参数 `/dev/sda1`。
## 特殊参数变量
Shell 提供了特殊的变量来处理参数信息。
| 变量 | 描述 |
| :--- | :--- |
| `$0 | 脚本本身的名称 |
| $1` - `$9 | 第 1 到第 9 个参数 |
| ${10}`+ | 第 10 个及以上的参数(必须使用花括号) |
| `$# | 传递给函数的参数个数 |
| $@` | 传递给函数的所有参数(每个参数独立引用) |
| `$* | 传递给函数的所有参数(合并为一个字符串) |
| $$` | 当前脚本的进程 ID (PID) |
| `$? | 上一个命令或函数的退出状态(0 表示成功) |
创建一个新函数 sum_all 来演示参数处理:
sum_all() {
echo "收到了 $# 个参数"
echo "参数列表: $@"
local total=0
for num in "$@"; do
total=$((total + num))
done
echo "总和是: $total"
}
sum_all 10 20 30
```
**执行**上述代码,输出将显示参数个数、列表及总和。
---
## 返回值
Shell 函数有两种返回数据的方式:**退出状态码**和**标准输出**。
### 1. 使用 return 返回状态码
`return` 只能返回 0-255 之间的整数,通常用于表示执行成功或失败。
**输入**以下示例:
```bash
check_file() {
if [ -f "$1" ]; then
return 0 # 成功
else
return 1 # 失败
fi
}
check_file "/etc/passwd"
if [ $? -eq 0 ]; then
echo "文件存在"
else
echo "文件不存在"
fi
```
### 2. 使用 echo 返回数据(推荐)
如果需要返回字符串或大于 255 的数值,**使用** `echo` 输出并在调用时**捕获**。
**修改**函数以返回计算结果:
```bash
calculate() {
local result=$(( $1 + $2 ))
echo "$result"
}
# 捕获返回值
my_sum=$(calculate 100 200)
echo "计算结果: $my_sum"
```
---
## 局部变量
默认情况下,Shell 脚本中的变量是全局的。在函数内部定义的变量会污染脚本主流程。**使用** `local` 关键字定义局部变量,限制其作用域仅在函数内部。
**对比**以下两种情况:
**情况一(全局变量,不推荐):**
```bash
test_scope() {
var="我是全局变量"
}
test_scope
echo "外部访问 var: $var" # 会输出 "我是全局变量"
情况二(局部变量,推荐):
test_scope() {
local var="我是局部变量"
}
test_scope
echo "外部访问 var: $var" # 输出为空
```
**养成**在函数内部定义变量时始终**加上** `local` 的习惯,以避免变量名冲突导致的难以排查的错误。
---
## 实战示例:日志记录函数
**编写**一个通用的日志记录函数,结合参数、返回值和局部变量。
**创建**脚本 `logger.sh`:
```bash
#!/bin/bash
LOG_FILE="./app.log"
# 定义日志函数
add_log() {
local level="$1"
local message="$2"
local timestamp=$(date "+%Y-%m-%d %H:%M:%S")
echo "[$timestamp] [$level] $message" >> "$LOG_FILE"
echo "日志已写入: $message"
}
# 使用函数记录不同级别的日志
add_log "INFO" "脚本开始执行"
add_log "ERROR" "连接数据库失败"
add_log "INFO" "脚本尝试重试..."
运行脚本:
chmod +x logger.sh
./logger.sh
查看日志文件内容:
cat app.log
暂无评论,快来抢沙发吧!