【发布时间】:2011-12-17 21:16:22
【问题描述】:
我在使用 Windows 命令解释器时遇到了一个非常奇怪的问题。它发生在 XP 和 Windows 7 上。我下面的描述适用于 Perl 脚本,但这个问题适用于在命令行上运行任何类型的程序,它需要命令行参数。
对于一个测试,我正在使用 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]
正如预期的那样。特殊字符 | 在双引号内可以正常工作,但在外引号时,您可以使用 ^ 转义它们。
但是,当双引号被添加到引用的参数时,例如在
perl check-params.pl "a\" b|<>"
然后我得到错误 -
> was unexpected at this time.
但如果双引号出现在 特殊字符 | 之后,然后就可以正常工作了。
您可以通过转义特殊 | 来轻松解决此问题 char 与 ^ 在带引号的参数内。 例如
perl check-params.pl "a\" b^|"
然而,转义的双引号不仅会影响特殊字符 | 在 current 参数中,但它会影响任何后续参数中的这些特殊字符。
例如,如果我这样做 -
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"
有效,因为 \" 出现在特殊字符 | 之后。
这一定是命令解释器中的错误。我有兴趣了解更多关于此的信息,并在可能的情况下找到解决方法。这个问题搞砸了一些有用的脚本。对于命令解释器来说,这是一个非常明显的问题。我也在 Windows 7 上试过,上面的 echo 测试也出现了同样的问题。
其他信息:
我更新了脚本 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 提到的 ^" 就是一个例子。有时您可以重新制作正则表达式以避免使用 ".如果在特殊字符 | 之前有两个 \" 序列,则不会出现问题。在运行任何命令之前,我运行 check-params.pl 和 check-pipe.pl 以验证 Perl 脚本将如何查看命令行参数,例如,对我的 OP 的上述编辑描述了这些脚本,这些脚本是我自 OP 以来修改的。
【问题讨论】:
-
尽管我相信我已经为您找到了解决方案(请参阅我的答案的最新编辑),如果您以交互方式输入正则表达式,您可能会发现脚本提示它们更方便而不是将它们放在命令行上。这样您就不必转义所有特殊字符。
-
非常感谢您的信息。我从我的 OP 中的测试中得到的印象是 \" 是一个转义序列。通过提示输入命令行参数对我来说是不可行的,因为我有很多命令而且它们非常复杂。我复制并粘贴它们从一个文本文件中,有时我会复制几个并一次运行它们。(在快速编辑模式下,您只需右键单击以粘贴到命令窗口中)。
标签: windows escaping command-prompt