繁体   English   中英

在Windows命令提示符中转义双引号副作用

[英]Escaped Double Quote Side Effect in Windows Command Prompt

我遇到了Windows命令解释器的一个非常奇怪的问题。 它出现在XP和Windows 7上。我的描述适用于Perl脚本,但是这个问题适用于在命令行上运行任何类型的程序,它接受命令行参数。

对于测试,我使用Perl脚本check-params.plcheck-params.pl输出它看到的参数 -

use strict;
use warnings;
while (my $param = shift @ARGV) {
    print "Param: [$param]\n";
}

因此,如果我跑 -

perl check-params.pl "a b|<>" c^|^<^>cc

然后输出是

[Param: a b|<>]
[Param: c|<>cc]

正如所料。 特殊的字符| <>在双引号内工作正常,但在外部引号时,你用^来转义它们。

但是,当引用的参数添加双引号时,例如

perl check-params.pl "a\" b|<>"

然后我得到错误 -

> was unexpected at this time.

但如果双引号出现特殊的char |之后 <或>,然后它工作正常。

你可以通过转义特殊的|来轻松解决这个问题 <> char,带引号参数内的^。 例如

perl check-params.pl "a\" b^|"

但是,转义的双引号不仅影响特殊字符| 当前参数中的<>但它会影响任何后续参数中的这些特殊字符。

例如,如果我这样做 -

perl check-params.pl "aa \"bb" ccc | perl check-pipe.pl

(其中check-pipe.pl只输出管道收到的内容 -

use strict;
use warnings;
while (<STDIN>) {
    print "PIPE RECEIVED ---> $_";
}

然后输出是 -

Param: [aa "bb]
Param: [ccc]
Param: [|]
Param: [perl]
Param: [check-pipe.pl]

即它对待管道 作为文字字符,没有管道发生。

有没有人有这个问题的经验,知道任何解决方法?

我编写了一些用于处理Web日志文件的Perl脚本,并且使用了正则表达式,我在命令行上的一个引用的参数中传递。 正则表达式可能包含诸如|之类的字符 <>,它也可能有一个双引号,我输入为“。”因此上面的问题正在出现。

任何帮助非常感谢,谢谢。


感谢您的回复,但在XP SP3上尝试此操作时,Perl脚本会看到两个命令行参数。

这个问题与Perl无关,例如

echo "a \"b|c"

产生错误 -

'c"' is not recognized as an internal or external command,
operable program or batch file.

echo "a b|\"c"

工作,因为\\“来自特殊的char |。

它必须是命令解释器中的错误。 我有兴趣了解更多相关信息,并在可能的情况下找到解决方法。 这个问题困扰着运行一些有用的脚本。 对于命令解释器来说,这是一个非常明显的问题。 我也试过Windows 7,并且上面的回声测试也出现了同样的问题。


附加信息:

我更新了脚本check-params.pl和check-pipe.pl以提供更多有用的信息: -

check-params.pl: -

use strict;
use warnings;
while (my $param = shift @ARGV) {
    print "COMMAND LINE RECEIVED: [$param]\n";
}

check-pipe.pl: -

use strict;
use warnings;
while (<STDIN>) {
    print "PIPE RECEIVED: $_";
}

while (my $param = shift @ARGV) {
    print "COMMAND LINE RECEIVED: [$param]\n";
}

例如跑步: -

perl pl/utils/check-params.pl l1 l1-b l1-c | perl pl/utils/check-pipe.pl l2 l2-b | perl pl/utils/check-pipe.pl l3 l3-b | perl pl/utils/check-pipe.pl united arsenal rangers raith

产生输出: -

PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1]
PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-b]
PIPE RECEIVED: PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l1-c]
PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2]
PIPE RECEIVED: PIPE RECEIVED: COMMAND LINE RECEIVED: [l2-b]
PIPE RECEIVED: COMMAND LINE RECEIVED: [l3]
PIPE RECEIVED: COMMAND LINE RECEIVED: [l3-b]
COMMAND LINE RECEIVED: [united]
COMMAND LINE RECEIVED: [arsenal]
COMMAND LINE RECEIVED: [rangers]
COMMAND LINE RECEIVED: [raith]

从而确认此命令行将按预期工作。 这些脚本可以在命令行上使用任意数量的管道。


附加信息:

我发现我可以使用多种解决方法来实现这一点 - 例如^“Harry提到的是一个例子。有时你可以重新制作正则表达式以避免使用”。 当在特殊char | <>之前有两个“序列”时,问题就不会发生。在运行任何命令之前,我运行check-params.pl和check-pipe.pl来验证Perl脚本将如何看到命令行参数,例如上面对我的OP的编辑描述了这些脚本,我从OP开始修改了这些脚本。

\\“中的双引号被认为与初始双引号相匹配,结束了引用的参数。要在引用参数中包含双引号,请使用两个双引号:

perl check-params.pl "a"" b|<>"

应该产生你期望的结果,这取决于perl.exe如何解析命令行参数(我已经使用命令脚本测试,因为我没有安装Perl)。 您需要更改脚本,以便将“”而不是“”视为双引号。

附加 :此命令行

echo "a \"b|c"

导致错误消息开始c" is not recognized这不是错误。

反斜杠不是转义字符,因此命令行包含一个带引号的字符串( "a \\" )后跟一个管道( | ),这使得其余的命令( c" )成为一个附加命令,来自echo命令的输出通过管道输出成。

如果你反而说

echo "a ""b|c"

然后只有一个带引号的字符串( "a ""b|c" ),它将按预期工作。

不幸的是,我现在可以确认ActivePerl的命令行解析导致了

perl check-params.pl "a"" b|"

分为两个参数。 您可能需要获取整个命令行(如果有办法在Perl中执行此操作)并自己解析它。

附加

perl check-params.pl ^"a\^" b^|c^"

产生预期的结果。 这可以通过转义所有特殊字符(包括引号)来实现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM