如何在Bash中正确加载.env文件中的复杂环境变量?
解决Bash中加载.env文件复杂变量的问题
之前用xargs或简单循环失效的核心原因是:这类方法会把空格、引号、括号等特殊字符当成字段分隔符,导致JSON这类带结构的变量值被截断或解析错误。下面提供两种可靠的实现方案,均支持忽略注释行并完整导出所有变量。
方案一:纯Bash函数实现
这个函数能处理空行、注释行,正确解析带特殊字符的变量值,还能自动去除值两端的单/双引号:
load_env() { local env_file="${1:-.env}" [[ ! -f "$env_file" ]] && { echo "错误:未找到.env文件 $env_file" >&2; return 1; } while IFS= read -r line; do # 跳过空行、以#或;开头的注释行 [[ "$line" =~ ^[[:space:]]*(#|;|$) ]] && continue # 仅拆分第一个=号,避免值中的=号干扰 if [[ "$line" =~ ^([^=]+)=(.*)$ ]]; then local var_name="${BASH_REMATCH[1]}" local var_value="${BASH_REMATCH[2]}" # 移除值两端的单引号或双引号 if [[ "$var_value" =~ ^\"(.*)\"$ ]]; then var_value="${BASH_REMATCH[1]}" elif [[ "$var_value" =~ ^\'(.*)\'$ ]]; then var_value="${BASH_REMATCH[1]}" fi # 导出变量 export "$var_name"="$var_value" fi done < "$env_file" }
使用方式
- 加载当前目录的
.env:load_env - 加载指定路径的.env文件:
load_env /path/to/your.env
方案二:awk配合source实现
用awk生成标准的export命令,再通过source执行,适合追求简洁的场景:
awk ' /^[[:space:]]*(#|;|$)/ { next } /^[^=]+=/ { split($0, parts, "=", 2) var_name = parts[1] var_value = parts[2] # 移除值两端的引号 gsub(/^["'\''"]|["'\''"]$/, "", var_value) printf("export %s=\"%s\"\n", var_name, var_value) } ' .env | source /dev/stdin
测试示例
假设你的.env文件内容如下:
# 普通配置 APP_NAME=MyApp DEBUG=true # JSON格式复杂变量 NODE_CONFIG='{"database": {"host": "localhost", "port": 5432}, "features": ["auth", "logging"]}' ; 分号开头的注释 API_KEY="abc123!@#$%^&*()"
执行方案后,运行echo $NODE_CONFIG即可看到完整的JSON内容,不会出现截断问题。
内容的提问来源于stack exchange,提问作者Luice712
相关产品推荐
相关产品推荐

