[英]Escaped Double Quote Side Effect in Windows Command Prompt
我遇到了Windows命令解释器的一个非常奇怪的问题。 它出现在XP和Windows 7上。我的描述适用于Perl脚本,但是这个问题适用于在命令行上运行任何类型的程序,它接受命令行参数。
对于测试,我使用Perl脚本check-params.pl
, check-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.