我有一个 abc.yml 文件,如下所示,其中包含用户名和密码参数。我已将这些参数存储在我的 linux 用户的 env 变量中,但是当应用程序执行 abc.yml 文件时,它不是打印 env 变量的值。它只是打印环境变量。
abc.yml:
type: MYSQL
host: localhost
port: 3307
username: '${user_mysql}'
password: '${pass_mysql}'
Linux 终端环境变量检查:
[arc@rnd-2 conn]$ echo ${user_mysql}
root
[arc@rnd-2 conn]$ echo ${pass_mysql}
notmypassword
执行 abc.yml 文件时的日志:
Caused by: java.sql.SQLInvalidAuthorizationSpecException: (conn=375) Access denied for user '${user_mysql}'@'localhost' (using password: YES)
Current charset is UTF-8. If password has been set using other charset, consider using option 'passwordCharacterEncoding'
答案1
除非你的 Java (?) 程序知道在看到某种形状时查找环境变量,否则${variable}
它无法在本地工作。
但是,您可以解析 YAML 文件并替换变量的值,然后让您的程序使用处理后的 YAML 文件。可以帮助您解决此问题的工具是envsubst
答案2
我们可以使用 YAML 感知工具来设置顶层username
和password
键的值,而不是尝试匹配 YAML 文件中的变量。这样做的好处是可以为文档对值进行适当的编码。
我们的想法是,在尝试将 YAML 文档与任何读取它的软件一起使用之前,对其进行适当修改(或创建其修改后的副本)。
以下是使用yq
Andrey Kislyuk 提供的基于 Python 的工具,它是著名的 JSON 处理器的包装器jq
。
请注意,密码以文字制表符结尾,以表明它支持任意字符串。我还插入了一些斜杠和反斜杠(人们可能希望在密码中看到的字符)。
user_mysql=ruut
pass_mysql='not\/my\/password '
yq -y \
--arg username "$user_mysql" \
--arg password "$pass_mysql" \
'. += $ARGS.named' abc.yml
键不需要出现在输入中才能工作,但如果存在,它们的值将被命令行上传递的参数覆盖。
给定问题中的输入文档,这将输出以下内容:
type: MYSQL
host: localhost
port: 3307
username: ruut
password: "not\\/my\\/password\t"
要“就地”进行更改,请yq
与 it--in-place
或-i
选项一起使用。
你也可以这样做yq
Mike Farah 提供的基于 Go 的工具:
user_mysql=ruut
pass_mysql='not\/my\/password '
export user_mysql pass_mysql
yq '.username = strenv(user_mysql) |
.password = strenv(pass_mysql)' abc.yml
请注意,在这种情况下,设置值的语法有些不同。我通过环境传递变量并在表达式strenv()
内部读取它们的值yq
。这意味着这两个变量都必须导出,或者以其他方式提供给yq
进程环境。
如果有选项,该yq
实用程序还可以进行“就地”编辑-i
。
给出问题中的文档的输出:
type: MYSQL
host: localhost
port: 3307
username: 'ruut'
password: "not\\/my\\/password\t"