使用 jq 提取和传播多个值的 Shell 技巧
内容提要
本文介绍了使用jq从Terraform中提取和传播多个值的方法。作者通过使用terraform show -json命令获取Terraform状态的JSON输出,并使用jq提取所需的两个值。作者还分享了一个使用jq和psql的解决方案,以从Terraform状态中提取密码和数据库主机,并打开与数据库的会话。作者解释了如何使用输入重定向和进程替换来传递这两个值给psql命令,并提到了使用分组命令来解决变量安全性问题。
延伸解读
为什么需要输入重定向而非管道
在 bash 等 shell 中,管道中的每个命令会在独立的子 shell 中执行,因此通过管道传递给分组命令的变量在分组命令结束后会丢失。文章使用输入重定向和进程替换,将 jq 的输出直接作为分组命令的标准输入,这样变量就在当前 shell 上下文中被读取和保留,从而提高了脚本在不同 shell 间的可移植性。
分组命令与子 shell 的安全作用
文章使用花括号 { ... } 将多个命令组合成一个单元,使输入重定向作用于所有命令,从而一次性读取主机和密码。而使用圆括号 ( ... ) 则创建一个子 shell,在其中执行 psql 会话。当会话结束时,子 shell 被销毁,其中定义的变量也随之消失,避免了敏感信息在会话结束后残留在当前 shell 中。
jq 提取值的顺序与稳定性
jq 表达式通过两个独立的 select 调用分别提取密码和主机地址,并将它们放入括号中作为单独表达式,使输出各占一行。文章指出,输出的顺序由输入 main.tf 文件中资源定义的顺序决定,因此是稳定的。这保证了后续 read 命令能按预期将第一行赋给 host,第二行赋给 password。
Q&A
如何使用jq从Terraform中提取多个值?
可以使用terraform show -json命令获取Terraform状态的JSON输出,然后通过jq提取所需的值。
提取的两个值是什么?
提取的两个值是数据库的随机密码和主机URL。
如何将提取的值传递给psql命令?
可以使用输入重定向和进程替换将提取的值传递给psql命令。
使用分组命令有什么好处?
使用分组命令可以确保变量在会话结束后不会保留,从而提高安全性。
为什么要避免将Terraform输出存储在文件中?
存储Terraform输出在文件中会污染工作区,因此应避免这样做。
如何确保提取的值在不同的Shell中都能使用?
通过使用输入重定向而不是管道,可以提高解决方案在不同Shell中的可移植性。