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

如何将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容器,它可以通过Docker中包含的OpenVPN连接执行用户提供的命令,例如,
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}
有效,但想知道更好的主意。这就是我要使用的。