这是一个简单的.bat
文件,显示了执行bat文件的前三个参数:
@echo 1: %1
@echo 2: %2
@echo 3: %3
当我像这样执行bat文件时
c:\> x:\show_parameters.bat "foo bar" baz "one two three"
输出
1: "foo bar"
2: baz
3: "one two three"
我很惊讶,因为我没想到双引号会作为参数的一部分传递。
当我使用Perl脚本显示参数值
时my $arg_cnt = 1;
for my $arg (@ARGV) {
printf "%2d: %s\n", $arg_cnt, $arg;
$arg_cnt++;
}
并像这样执行脚本
c:\> x:\show_parameter.pl "foo bar" baz "one two three"
打印
1: foo bar
2: baz
3: one two three
即没有任何双引号。这是蝙蝠变种的预期行为。
那么,为什么参数以不同的方式传递给bat文件?
答案 0 :(得分:1)
TL; DR:这取决于shell的实现。在Windows上,cmd
控制台引用使用与bash shell不同的规则。 source
我相信你一直在寻找:
@echo 1: %~1
@echo 2: %~2
@echo 3: %~3
Tilde角色有特殊的"修饰符"批处理参数的含义。如果你考虑一下,Perl和批处理是两种不同的语言,当一个程序被发送参数时,想想它就像它传递了一个查询字符串,除了它决定如何解析语言它。真正传递给程序的是一个长参数但是程序在空格上分开,同时牢记引号和转义。
您还可以看到@echo 0: %0
会在引号中显示该程序,而@echo 0: %~0
会删除双引号。
要查看"参数"的全部内容。传递给脚本,没有被解析,你做了:
@echo *: %*
正如您所看到的,脚本实际上是传递一个长参数并且必须首先解析,保留空格和引号,并记住^
之类的转义字符,以便创建多个"论证的概念"。
就Perl的行为而言,我的猜测是Perl在填充ARGV
时会自动为您执行此操作。如果您对Perl使用的逻辑感兴趣,可以查看source code。
修改强>:
在玩了一段时间后,我开始认为这超出了Perl的控制范围。在从命令行测试print_r($argv);
时,我也注意到与PHP相同的行为,它也会丢失其引号。
您可以通过运行:
看到Perl通过引号发送参数use Win32::API;
my $GetCommandLine = Win32::API->new('kernel32',
'GetCommandLine', [ ] , 'P' );
$cmdline = $GetCommandLine->Call();
print $cmdline;
但是,如果您只想要参数而不是完整的命令行命令,那么您需要解析它。
这里发布的问题与您的完全一样:
http://www.nntp.perl.org/group/perl.beginners/2002/07/msg29597.html
在第二页上解释彼得斯科特的回答:在程序看到参数之前,shell会执行空格分裂和解释,并且程序编写的语言没有区别。所以你必须要找到一个解决方法。
答案是非常一致的,它是一个shell问题,我研究的越多 例如,即使在Python中,它也是same issue。
那为什么批次会给出不同的结果呢?这取决于shell的实现。在Windows上,cmd控制台引用使用与bash shell不同的规则。
答案 1 :(得分:0)
考虑
call :somesubroutine %*
如果没有引号,somesubroutine
会看到6个参数。看到3。
真的是定义问题,但批量似乎在这里说实话。
还要考虑
会发生什么x:\show_parameters.bat "foo bar" "" "one two three"