如何将shell命令行参数转义并存储到一个参数中?
如果有人说这是一个坏主意,实际上这是一个合理的方法 我正在编写这个Docker容器,它可以通过Docker中包含的OpenVPN连接执行用户提供的命令,例如,如何将shell命令行参数转义并存储到一个参数中?,shell,docker,Shell,Docker,如果有人说这是一个坏主意,实际上这是一个合理的方法 我正在编写这个Docker容器,它可以通过Docker中包含的OpenVPN连接执行用户提供的命令,例如,Docker运行vpntunnel curl example.com 因此,映像的入口点将启动OpenVPN,在VPN隧道启动后,执行用户提供的命令行 问题是,OpenVPN启动后运行命令的标准方法是通过OpenVPN的--up选项。以下是此选项的手册页说明: --up cmd Run command cmd after success
Docker运行vpntunnel curl example.com
因此,映像的入口点将启动OpenVPN,在VPN隧道启动后,执行用户提供的命令行
问题是,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$@”
,但它肯定无法区分abc
和“abc
之间的命令行。在bash 4.4+中,您可以使用参数转换@
引用值:
--up "tunnel-up.sh ${*@Q}"
在以前的版本中,您可以使用printf“%q”
来实现相同的效果:
--up "tunnel-up.sh $((($#)) && printf '%q ' "$@")"
(在调用
printf
之前,($)
检查确保有要打印的参数)您是否尝试像这样传递它--up
?这将使您能够避免将--up
作为入口点的一个选项。有没有相反的方法?i、 在一个变量中给定一个带引号的命令行,将其恢复为当前位置参数。我尝试了export CMD=“${*@Q}”
然后set--${CMD}
但没有反转义参数。发现eval set--${CMD}
有效,但想知道更好的主意。这就是我要使用的。