5.3.3 函数定义、参数与返回值

函数定义、参数与返回值#

函数用于封装可复用逻辑,提升脚本可读性与可维护性。Bash 函数无需声明类型,遵循“先定义后调用”的原则。

原理草图:函数调用与返回值流转#

文章图片

1. 安装与环境准备(确保 Bash 支持)#

# Debian/Ubuntu
sudo apt-get update
sudo apt-get install -y bash

# RHEL/CentOS
sudo yum install -y bash

# 验证版本
bash --version

命令解释:
- apt-get/yum install bash:安装 Bash 解释器
- bash --version:查看版本,确认可用

2. 函数定义与调用(含参数与返回值)#

#!/usr/bin/env bash
# /tmp/func_demo.sh

# 函数定义:function 关键字可省略
sum() {
  local a="$1"
  local b="$2"
  local result=$((a + b))
  echo "$result"          # 输出结果供调用方使用
  return 0                # 返回状态码:0 表示成功
}

# 调用函数并获取输出
total="$(sum 3 5)"
echo "sum(3,5) = $total"

# 返回值(状态码)示例
check_dir() {
  local dir="$1"
  if [ -d "$dir" ]; then
    return 0
  else
    return 1
  fi
}

check_dir "/etc"
echo "check_dir /etc => $?"   # 0 表示存在

check_dir "/noexist"
echo "check_dir /noexist => $?" # 1 表示不存在

命令解释:
- local:定义函数内局部变量,避免污染全局
- echo:输出值给调用方(命令替换获取)
- return:仅返回状态码(0-255),不可直接返回大数或字符串
- $?:获取上一条命令/函数返回状态码

3. 参数处理与默认值示例#

#!/usr/bin/env bash
# /tmp/param_demo.sh

greet() {
  local name="${1:-world}"   # 如果未传参,默认 world
  local times="${2:-1}"      # 默认执行 1 次
  for ((i=1; i<=times; i++)); do
    echo "Hello, $name ($i)"
  done
}

greet
greet "linux" 3

命令解释:
- ${1:-world}:若 $1 为空,使用默认值
- for ((...)):C 风格循环

4. 排错与常见问题#

# 1) 语法错误:函数未定义即调用
./script.sh: line 5: foo: command not found
# 解决:确保 foo 函数在调用前定义

# 2) 返回值误用:return 传大数或字符串
return "ok"
# 解决:return 仅支持 0-255,返回字符串用 echo + 命令替换

# 3) 变量污染:未用 local
sum() { a=1; }   # 可能覆盖全局变量 a
# 解决:使用 local a=1

5. 实战小示例:检查服务端口并返回状态#

#!/usr/bin/env bash
# /tmp/port_check.sh

check_port() {
  local port="$1"
  if ss -lnt | awk '{print $4}' | grep -q ":${port}$"; then
    echo "port $port is listening"
    return 0
  else
    echo "port $port is NOT listening"
    return 1
  fi
}

check_port 22
echo "status=$?"

命令解释:
- ss -lnt:列出 TCP 监听端口
- awk '{print $4}':提取本地地址列
- grep -q:安静模式,仅返回状态码

6. 练习#

  1. 编写函数 backup_file,输入文件路径,若存在则复制到 /tmp/backup/ 并返回 0,否则返回 1。
  2. 编写函数 avg,输入多个数字(使用 $@),输出平均值。
  3. 写一个脚本,调用 check_dir 函数判断 /var/log,若存在则统计日志文件数并输出。