我遇到了Windows命令解释器的一个非常奇怪的问题。它发生在XP和Windows 7上。我的下面的描述适用于Perl脚本,但是这个问题适用于在命令行上运行任何类型的程序,其中包含命令行参数。在Windows命令提示符中出现双引号副作用
对于我使用的Perl脚本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]
如预期。特殊字符| <>在双引号内工作良好,但是当外引号用^来转义时。
然而,当一个双引号被添加到引用PARAM例如,在
perl check-params.pl "a\" b|<>"
然后我得到的错误 -
> was unexpected at this time.
但是,如果双引号特殊字符后,来到| <或>,那么它工作正常。
你可以通过转义特殊| <>带引号的参数内的^字符。 如
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]
即它对待管道|作为文字字符,并且不会出现管道。
有没有人有任何这个问题的经验,并知道任何解决方法?
我已经编写了一些Perl脚本来处理Web日志文件,还有一个使用了正则表达式,我在命令行中使用了引用参数。正则表达式可能包含诸如|的字符<>,它也可能有一个双引号,我输入为“。因此,上述问题正在出现。
任何帮助非常感谢,谢谢。
感谢您的回复,但在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"
作品,因为\”而来的特殊字符之后| 。
It必须是命令解释器中的错误。我想知道更多关于此的信息,并在可能的情况下找到解决方法。这个问题混淆了运行一些有用的脚本。对于一名命令解释者来说,这是一个非常明显的问题。我也尝试过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]
因此证实了如预期此命令行会工作。这些脚本可以在命令行上使用任意数量的管道。
附加信息:
,我觉得我能得到这个使用多种解决方法的工作 - 例如^“哈利提到的一个例子有时你可以recraft正则表达式,以避免使用。”如果在特殊字符前有两个“序列”,则不会发生问题。在运行任何命令之前,我运行check-params.pl和check-pipe.pl来验证Perl脚本如何看到命令行参数,例如上面的OP编辑描述了这些脚本,这些脚本自从我的OP以来我已经修改过了。
虽然我相信我找到了解决方案(请参阅我的答案的最新编辑),如果您以交互方式输入正则表达式,您可能会发现脚本更方便地提示它们,而不是将它们放在命令行。这样你就不必逃避所有的特殊字符。 –
非常感谢您的信息。我从我的OP测试中获得了“转义序列”的印象,对我来说,通过提示输入命令行参数是不可行的,因为我有很多命令,而且它们非常复杂。他们从一个文本文件,有时我复制几个并一次运行它们(使用快速编辑模式,你可以右键单击粘贴到命令窗口) –