Shell 脚本中如何定义函数?参数传递和返回值怎么处理?
Shell 函数用 name() { } 或 function name { } 定义,调用时直接写函数名。参数通过 $1、$2、$@ 等位置变量访问,不写在括号里。返回值有两个机制:return 只能返回 0-255 的退出码,用于表示成功或失败;要返回字符串或计算结果,需用 echo 输出后由调用方通过 $(func) 命令替换捕获。函数内变量默认是全局的,必须用 local 声明才能限定作用域,这是 Shell 和大多数语言的重要区别。
追问
1. return 和 echo 返回值有什么本质区别? return 设置的是函数的退出状态码(0-255),只能用于条件判断(if func; then)。echo 输出到 stdout,由 $(func) 捕获后可当字符串使用。两者常配合:echo 返回结果,return 返回状态。
2. $@ 和 $ 有什么区别?什么时候加引号?* 不加引号时两者相同,展开为独立单词。加引号后 "$@" 保留每个参数的边界("$1" "$2" ...),"$*" 把所有参数合并为一个字符串("$1 $2 ...")。循环遍历参数时始终用 "$@"。
3. 函数中不用 local 会怎样? 变量变成全局的,会污染外部作用域甚至覆盖同名变量。这在调试时极难排查,是 Shell 脚本 bug 的常见来源。建议所有函数内变量都加 local。
4. 如何在另一个脚本中复用函数? 将函数写在独立文件中,用 source 或 . 命令导入。也可以用 export -f func_name 将函数导出给子进程,但只对 bash 子进程有效。
5. 函数能递归调用吗?有什么限制? 可以递归,但 Shell 没有尾递归优化,深度递归会很快耗尽栈空间。实际中递归深度超过几百层就会报错,复杂数据结构建议用其他语言。
写段代码
bash# return 退出码 + echo 返回值 grep_key() { local file=$1 key=$2 grep -q "$key" "$file" || return 1 grep "$key" "$file" | head -1 } result=$(grep_key /etc/hosts localhost) if [ $? -eq 0 ]; then echo "Found: $result" fi