将复杂配置作为命令行(而不是文件)传递的好方法是什么?

What is a good way to pass complex configuration as a command-line (not a file)?

提问人:CplusPuzzle 提问时间:11/7/2023 最后编辑:David MazeCplusPuzzle 更新时间:11/7/2023 访问量:59

问:

假设我希望能够运行一个将 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

评论


答:

2赞 KamilCuk 11/7/2023 #1

出于某种原因,这是一个坏主意吗?

是的,它是完全不可读的。您必须拥有 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。

评论

0赞 CplusPuzzle 11/7/2023
我是否不必担心配置文本中的字符提前终止参数字符串、字符转义等?关于可读性和 Git,程序会在运行时将解码的未压缩配置保存到一个文件中,在提交到 Git 时,您会希望原始配置文本也被提交。你确定有那么糟糕吗?有什么可以说的,命令更短,没有任何换行符吗?
0赞 KamilCuk 11/7/2023
won't I have to worry正确引用是用户的工作。Python 的引用规则与 shell 截然不同。用户的工作是知道他输入了什么,并知道如何在他输入的环境中表示它。YAML可以是单行。subprocess.run(["./myprogram", "-e", """ something """]){ a: { b: [c, d, e] } }
1赞 Sourav 11/7/2023 #2

在压缩配置后将配置编码为命令行参数作为 base64 字符串的方法是一种可行且功能强大的解决方案,用于将复杂配置作为命令行参数传递。如你所述,它通常用于各种上下文,包括在容器中运行应用程序时。

然而

虽然您的方法很简单,但当配置变得更加复杂时,它可能会变得不那么方便。在处理大型或嵌套配置时,维护和解码这些 base64 编码的字符串可能会变得具有挑战性。base64 编码的字符串无法通过人类读取,使用户难以查看或修改配置。与他人合作或进行故障排除时,可读性可能是一个问题。

与其直接在命令行中对配置进行编码,不如考虑使用环境变量、配置文件,甚至是容器化应用程序的 Kubernetes ConfigMap 或 Secrets。这些是用于管理配置的更传统的方法。对于 Docker 容器,Docker Swarm 和 Kubernetes 提供了使用 secret 和 ConfigMap 处理敏感配置数据的解决方案。

始终选择最适合您的特定要求和用例的方法。

评论

0赞 CplusPuzzle 11/7/2023
感谢您的评论,您是否有使用这种技术的成熟产品的参考?