我有一个字符串列表,我想在单个 Windows 命令行调用中将这些字符串作为参数传递。对于简单的字母数字字符串,只需逐字传递它们就足够了:
> script.pl foo bar baz yes no
foo
bar
baz
yes
no
我知道如果参数包含空格或双引号,我需要反斜杠转义双引号和反斜杠,然后双引号参数。
> script.pl foo bar baz "\"yes\"\\\"no\""
foo
bar
baz
"yes"\"no"
但是,当我尝试用文字百分号传递参数时,会发生这种情况:
> script.pl %PATH%
C:\Program
Files\PHP\;C:\spaceless\perl\bin\;C:\Program
Files\IBM\Java60\bin;
(...etc.)
双引号不起作用:
> script.pl "%PATH%"
C:\Program Files\PHP\;C:\spaceless\perl\bin\;C:\Program Files\IBM\Java60\bin; (...etc.)
反斜杠转义也不起作用(注意反斜杠如何出现在输出中):
> script.pl \%PATH\%
\%PATH\%
此外,反斜杠转义的规则不一致反斜杠:
> script.pl "\\yes\\"
\\yes\
> script.pl "\yes\\"
\yes\
> script.pl "\yes\"
\yes"
此外,毫无疑问,Windows 命令行 shell 中存在特殊字符,就像所有 shell 中的特殊字符一样。 那么,在 Windows 命令行中安全转义任意命令行参数的一般过程是什么?
理想的答案将描述一个函数 escape()
,它可以是在如下情况下使用(Perl 示例):
$cmd = join " ", map { escape($_); } @args;
这里还有一些示例字符串,应该通过此函数安全地转义(我知道其中一些看起来像 Unix,这是故意的):
yes
no
child.exe
argument 1
Hello, world
Hello"world
\some\path with\spaces
C:\Program Files\
she said, "you had me at hello"
argument"2
\some\directory with\spaces\
"
\
\\
\\\
\\\\
\\\\\
"\
"\T
"\\T
!1
!A
"!\/'"
"Jeff's!"
$PATH
%PATH%
&
<>|&^
()%!^"<>&|
>\\.\nul
malicious argument"&whoami
*@$$A$@#?-_
I have a list of strings and I want to pass those strings as arguments in a single Windows command line call. For simple alphanumeric strings it suffices to just pass them verbatim:
> script.pl foo bar baz yes no
foo
bar
baz
yes
no
I understand that if an argument contains spaces or double-quotes, I need to backslash-escape the double-quotes and backslashes, and then double-quote the argument.
> script.pl foo bar baz "\"yes\"\\\"no\""
foo
bar
baz
"yes"\"no"
But when I try to pass an argument with literal percent signs, this happens:
> script.pl %PATH%
C:\Program
Files\PHP\;C:\spaceless\perl\bin\;C:\Program
Files\IBM\Java60\bin;
(...etc.)
Double quoting doesn't work:
> script.pl "%PATH%"
C:\Program Files\PHP\;C:\spaceless\perl\bin\;C:\Program Files\IBM\Java60\bin; (...etc.)
Nor does backslash-escaping (notice how the backslashes are present in the output):
> script.pl \%PATH\%
\%PATH\%
Also, the rules are inconsistent for backslash-escaping backslashes:
> script.pl "\\yes\\"
\\yes\
> script.pl "\yes\\"
\yes\
> script.pl "\yes\"
\yes"
Also, doubtless there are special characters in the Windows command line shell, much like there are in all shells. What, then, is the general procedure for safely escaping arbitrary command line arguments for use at the Windows command line?
The ideal answer will describe a function escape()
which can be used in situations like the following (a Perl example):
$cmd = join " ", map { escape($_); } @args;
Here are some more example strings which should be safely escaped by this function (I know some of these look Unix-like, that's deliberate):
yes
no
child.exe
argument 1
Hello, world
Hello"world
\some\path with\spaces
C:\Program Files\
she said, "you had me at hello"
argument"2
\some\directory with\spaces\
"
\
\\
\\\
\\\\
\\\\\
"\
"\T
"\\T
!1
!A
"!\/'"
"Jeff's!"
$PATH
%PATH%
&
<>|&^
()%!^"<>&|
>\\.\nul
malicious argument"&whoami
*@$A$@#?-_
发布评论
评论(2)
这是一篇 msdn 博客文章,展示了如何操作。但是,它假设每个命令行程序内部都使用 CommandLineToArgvW 来解析它的命令行(这不是一个破旧的假设,因为它是 Shell32 库的一部分)。
原始链接(可能不起作用):http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
Web 存档链接:https://web.archive.org/web/20190109172835/https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong -路/
Here is an msdn blogpost showing how. It however assumes that every command line program internally uses CommandLineToArgvW to parse it's command line (not a shabby assumption, since it's part of the Shell32 library).
Original link (may not work): http://blogs.msdn.com/b/twistylittlepassagesallalike/archive/2011/04/23/everyone-quotes-arguments-the-wrong-way.aspx
Web archive link: https://web.archive.org/web/20190109172835/https://blogs.msdn.microsoft.com/twistylittlepassagesallalike/2011/04/23/everyone-quotes-command-line-arguments-the-wrong-way/
要转义命令行参数,请使用以下命令:
要转义实际命令行命令,例如,在调用具有可笑名称(如
())的命令时!&%PATH%^;, .exe
(这是完全合法的),请使用以下命令:请注意,使用
escapeArg()
作为命令将不起作用。来源:
To escape a command line argument, use the following:
To escape the actual command line command, for example when invoking a command with a ridiculous name such as
()!&%PATH%^;, .exe
(which is perfectly legal), use the following:Note that using
escapeArg()
for the command will not work.Sources: