我需要从嵌入在另一个Mac/Windows应用程序中的Lua解释器运行一些Shell命令,其中Shell命令是实现某些操作(例如在浏览器中打开帮助页面)的唯一途径。如果我有一系列参数(可能是用户输入的结果),该如何转义每个参数以避免出错?
受this article启发,一个简单的解决方案似乎是转义所有非字母数字字符,在类Unix系统上使用
这对我来说似乎很合理,但有没有我可能忽略的陷阱? 我知道在bash中,后跟换行符的
受this article启发,一个简单的解决方案似乎是转义所有非字母数字字符,在类Unix系统上使用
\
,在Windows上使用^
。据我所知,这可以防止任何参数引起:
- 由于干扰换行符、
;
(Unix)或&
(Windows)而执行另一个命令 - 在Unix上使用
$
或`
进行命令替换 - 在Windows上使用
%
进行变量评估 - 重定向使用
<
、|
和>
这对我来说似乎很合理,但有没有我可能忽略的陷阱? 我知道在bash中,后跟换行符的
\\ 将有效地删除换行符,这在这里不是问题。
编辑
我的结论:没有单个机制可以通过交换转义字符在Windows和*nix上同时工作。 结果并不那么简单,因为要确保Windows程序实际上看到我们想要的命令行参数,需要处理Windows上的命令字符串拆分而不是由shell处理而是由所调用的程序本身处理。
因此,需要考虑两层转义:
- 首先,Windows shell将处理我们给出的内容。它可能会在
%
处进行变量替换,在&
处拆分成多个命令或在|
处将其传递给另一个命令。
- 然后,它将向调用的程序传递一个单个命令字符串,该程序将拆分该字符串,理想情况下但不一定遵循Microsoft描述的规则。
假设遵循这些规则,就可以逆向操作,首先转义这些规则,然后进一步为shell转义。
execve
,其中参数是单独传递的,但Windows则在单个命令行字符串中传递参数。尽管Windows有指导方针和内置实用程序来解析命令行,但每个程序都可以制定自己的命令行解析规则。请查看 https://blogs.msdn.microsoft.com/larryosterman/2007/10/03/the-windows-command-line-is-just-a-string/ 和 http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx。 - Gumbo