shell函数中变量默认全局,需用local显式声明局部变量以避免污染;支持多变量初始化、花括号动态命名及-i/-r/-a等类型属性。

在Shell函数中不加限制地定义变量,默认就是全局的,会覆盖同名外部变量,造成意外污染。要真正隔离作用域,必须显式声明局部变量。
用 local 关键字声明函数内变量
这是最直接、最可靠的方式。只要在函数内部用 local 开头定义变量,它就只在该函数生命周期内有效,退出后自动销毁,不影响外部同名变量。
- 写法:在赋值前加上 local,等号前后不能有空格,例如 local count=0 或 local name(先声明再赋值)
- 支持同时声明并初始化多个变量:local a=1 b="test" c
- 若变量名含特殊字符或需拼接,建议用花括号包裹:local "${var_name}"(较少见,一般用于动态变量名场景)
避免常见错误写法
很多人误以为在函数里重新赋值就自然“局部化”了,其实不然。以下写法全部无效:
- a=100 —— 没有 local,仍是全局变量
- declare a=100 —— declare 默认也是全局的,除非加 -g(显式声明全局)或 -r/-i 等属性,但它本身不提供局部作用域
- local a; a=100 —— 合法,但注意分号不是必须,换行更清晰;如果漏掉 local,第二行仍会污染全局
验证局部性是否生效
可通过对比函数内外的变量值快速确认:
- 函数外定义 name="outer",函数内写 local name="inner",调用后 echo $name 输出仍是 outer
- 函数内未用 local,则函数外的 $name 会被覆盖为 inner
- 也可用 set | grep "^name=" 查看当前 shell 中是否存在该变量名(局部变量不会出现在 set 列表中)
补充:局部变量也支持类型属性
local 可与 declare 属性结合使用,增强语义和安全性:
- local -i num=42 —— 声明整型局部变量,后续赋非数字值会转为 0
- local -r const="API_V1" —— 声明只读局部常量,函数内无法再修改
- local -a arr=(1 2 3) —— 声明局部数组











