提问人:CplusPuzzle 提问时间:11/7/2023 最后编辑:David MazeCplusPuzzle 更新时间:11/7/2023 访问量:59
将复杂配置作为命令行(而不是文件)传递的好方法是什么?
What is a good way to pass complex configuration as a command-line (not a file)?
问:
假设我希望能够运行一个将 YAML 文件作为配置的命令行实用程序,并且我想添加另一个运行方法,以应对该实用程序无权访问该文件的情况(例如,它在新创建的 docker 容器中运行)。
我的想法是将 YAML 文件的内容进行 gzip 压缩,然后将输出编码为 base64 并使用字符串作为命令行参数,然后该实用程序可以执行相反的操作来生成其配置。
例如
$ echo "configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345" | gzip -fc | base64 -w0
H4sIAFrPSWUAA0vOz0vLTC8tSizJzM9TKEmtKFEwNDI2MeVKHloSAArBW9DIAAAA
反之亦然
$ echo "H4sIAFrPSWUAA0vOz0vLTC8tSizJzM9TKEmtKFEwNDI2MeVKHloSAArBW9DIAAAA" | base64 -d | gzip -dc
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
运行该实用程序可以通过以下任一方式完成,也可以通过以下方式完成./myprogram -f config.yaml
./myprogram -e "H4sIAFrPSWUAA0vOz0vLTC8tSizJzM9TKEmtKFEwNDI2MeVKHloSAArBW9DIAAAA"
这听起来很简单,是一种司空见惯的做法,但我还没有在任何地方看到它(这并不意味着什么)。
出于某种原因,这是一个坏主意吗?
有没有更好的司空见惯的方法?
我是否试图在这里重新发明轮子,即这是一个用我不知道的通用明显解决方案解决的问题吗?
先谢谢你。
答:
出于某种原因,这是一个坏主意吗?
是的,它是完全不可读的。您必须拥有 base64 和 gzip,它们并不总是可用的。这并不简单 - 您必须使用 base64 和 gzip。它在 git 版本控制系统中看起来非常糟糕,并且无法维护和读取以跟踪更改。
有没有更好的司空见惯的方法?
通常,工具从 stdin 读取。
$ ./myprogram -f - <<EOF
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
EOF
或者只是传递字符串:
$ ./myprogram -e 'configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345
configuration text 12345'
将复杂配置作为命令行(而不是文件)传递的好方法是什么?
使用标准输入或文本字符串或单独的文件描述符。如果用户想要将字符串重定向到文件描述符,则可以调用 Bash。
评论
won't I have to worry
正确引用是用户的工作。Python 的引用规则与 shell 截然不同。用户的工作是知道他输入了什么,并知道如何在他输入的环境中表示它。YAML可以是单行。subprocess.run(["./myprogram", "-e", """ something """])
{ a: { b: [c, d, e] } }
在压缩配置后将配置编码为命令行参数作为 base64 字符串的方法是一种可行且功能强大的解决方案,用于将复杂配置作为命令行参数传递。如你所述,它通常用于各种上下文,包括在容器中运行应用程序时。
然而
虽然您的方法很简单,但当配置变得更加复杂时,它可能会变得不那么方便。在处理大型或嵌套配置时,维护和解码这些 base64 编码的字符串可能会变得具有挑战性。base64 编码的字符串无法通过人类读取,使用户难以查看或修改配置。与他人合作或进行故障排除时,可读性可能是一个问题。
与其直接在命令行中对配置进行编码,不如考虑使用环境变量、配置文件,甚至是容器化应用程序的 Kubernetes ConfigMap 或 Secrets。这些是用于管理配置的更传统的方法。对于 Docker 容器,Docker Swarm 和 Kubernetes 提供了使用 secret 和 ConfigMap 处理敏感配置数据的解决方案。
始终选择最适合您的特定要求和用例的方法。
评论