如何转义任意字符串以用作 Windows 中的命令行参数?

发布于 2024-11-16 09:12:23 字数 1535 浏览 0 评论 0 原文

我有一个字符串列表,我想在单个 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$@#?-_

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

演出会有结束 2024-11-23 09:12:23

这是一篇 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/

死开点丶别碍眼 2024-11-23 09:12:23

要转义命令行参数,请使用以下命令:

sub escapeArg {
  my $arg = shift;

  # Sequence of backslashes followed by a double quote:
  # double up all the backslashes and escape the double quote
  $arg =~ s/(\\*)"/$1$1\\"/g;

  # Sequence of backslashes followed by the end of the arg,
  # which will become a double quote later:
  # double up all the backslashes
  $arg =~ s/(\\*)$/$1$1/;

  # All other backslashes do not need modifying

  # Double-quote the whole thing
  $arg = "\"".$arg."\"";

  # Escape shell metacharacters
  $arg =~ s/([()%!^"<>&|;, ])/\^$1/g;

  return $arg;
}

要转义实际命令行命令,例如,在调用具有可笑名称(如())的命令时!&%PATH%^;, .exe(这是完全合法的),请使用以下命令:

sub escapeCmd {
  my $arg = shift;

  # Escape shell metacharacters
  $arg =~ s/([()%!^"<>&|;, ])/\^$1/g;
  return $arg;
}

请注意,使用 escapeArg() 作为命令将不起作用。

来源:

To escape a command line argument, use the following:

sub escapeArg {
  my $arg = shift;

  # Sequence of backslashes followed by a double quote:
  # double up all the backslashes and escape the double quote
  $arg =~ s/(\\*)"/$1$1\\"/g;

  # Sequence of backslashes followed by the end of the arg,
  # which will become a double quote later:
  # double up all the backslashes
  $arg =~ s/(\\*)$/$1$1/;

  # All other backslashes do not need modifying

  # Double-quote the whole thing
  $arg = "\"".$arg."\"";

  # Escape shell metacharacters
  $arg =~ s/([()%!^"<>&|;, ])/\^$1/g;

  return $arg;
}

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:

sub escapeCmd {
  my $arg = shift;

  # Escape shell metacharacters
  $arg =~ s/([()%!^"<>&|;, ])/\^$1/g;
  return $arg;
}

Note that using escapeArg() for the command will not work.

Sources:

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文