先把边界说清楚:在 Bash 里,环境变量和数组不是一回事。Bash 手册说明,环境是子进程继承的 `name=value` 列表;而数组是 shell 内部的结构,索引数组从 0 开始,关联数组用字符串键 [1][2]。所以,`export` 能传字符串,不能把数组的结构原封不动地传给下一个进程。
步骤
- 单个值直接用 `export VAR=value`,适合 `PATH`、`HOME`、`TMPDIR` 这类本来就是字符串的参数。`environ(7)` 还专门说明,`PATH` 是用冒号分隔目录前缀的字符串,很多程序都按这个规则解析 [2]。
- 多个值如果必须跨进程,优先把它序列化成约定好的文本,例如冒号分隔、CSV,或者放进临时文件,再由子进程自行解析。不要指望 `export arr=(a b c)` 这种写法有魔法,它不会把数组语义一起带走 [1][2]。
- 如果逻辑只在当前脚本内流转,就把它留在 Bash 数组里,配合 `declare -a`、`read -a`、`${arr[@]}` 使用。需要遍历、拼接、过滤时,数组比手工拆字符串更稳,尤其是元素里包含空格、引号或通配符时 [1]。
这里最容易被忽略的,是“看起来能跑”和“结构真的没丢”完全不是一回事。举个现实场景,`LD_LIBRARY_PATH` 和 `PATH` 都是环境变量,很多部署脚本、容器启动脚本、CI 任务都会改它们;但如果你要传的是一组待执行命令、多个输入文件名或一串机器地址,靠环境变量硬塞,后面一旦碰到空格、换行或者空元素,就会出问题。
方法上更稳的分法其实很简单,单值进环境,列表留数组,复杂对象用文件或 JSON。前者是为了让子进程看到,后者是为了让 Bash 自己处理边界。Bash 的数组支持负索引、没有固定上限,这些优势都只在 shell 进程内部成立;一旦跨进程,就回到字符串世界 [1][2]。
如果你只想记一个操作原则,就记成这句:能不 `export` 的数组,尽量别 `export`;能不把列表打散成一个字符串,尽量别打散。你写脚本越久,就越会发现,稳定不是少写几行,而是少做一次不必要的转换。

全部 0条评论