gpt4 book ai didi

shell - 如何将shell命令行参数转义并将其存储到一个参数中?

转载 作者:行者123 更新时间:2023-12-02 19:27:10 24 4
gpt4 key购买 nike

Inb4的任何人都说这是个坏主意,实际上,这是解决此类问题的合理方法。

我正在编写这个Docker容器,该容器可以通过Docker中包含的OpenVPN连接执行用户提供的命令,例如docker run vpntunnel curl example.com

因此,镜像的ENTRYPOINT将启动OpenVPN,在VPN隧道启动后,执行用户提供的CMD行。

问题是,OpenVPN启动后运行命令的标准方法是通过OpenVPN的--up选项。这是此选项的手册页描述:

--up cmd
Run command cmd after successful TUN/TAP device open (pre --user UID change).
cmd consists of a path to script (or executable program), optionally followed
by arguments. The path and arguments may be single- or double-quoted and/or
escaped using a backslash, and should be separated by one or more spaces.

因此,这里的合理方法是让ENTRYPOINT脚本正确转义用户提供的CMD行,并将整个内容作为一个参数传递给OpenVPN的 --up选项。

万一我的Docker镜像需要在隧道启动后和执行用户命令行之前执行一些初始化,我可以在用户提供CMD行之前添加一个脚本,如下所示: --up 'tunnel-up.sh CMD...',在 tunnel-up.sh的最后一行中,使用 "$@"执行用户提供的参数。

现在,您可能已经猜到了,剩下的唯一问题是如何正确地转义整个命令行以能够作为单个参数传递。

天真的方法仅仅是 --up "tunnel-up.sh $@",但它肯定无法区分 a b c"a b" c之间的命令行。

最佳答案

在bash 4.4+中,您可以使用带@的参数转换来引用值:

--up "tunnel-up.sh ${*@Q}"

在以前的版本中,您可以使用 printf '%q'达到相同的效果:
--up "tunnel-up.sh $((($#)) && printf '%q ' "$@")"

( (($#))检查可确保在调用 printf之前有要打印的参数。)

关于shell - 如何将shell命令行参数转义并将其存储到一个参数中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55173752/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com