2013-04-04 67 views
5

问题: Windows XP未将命令行参数传递给perl脚本。

症状:一个简单的命令,如:

say "Argument 1 (\$ARGV[0]) is: $ARGV[0], argument 2 (\$ARGV[1]) is: $ARGV[1]."; 

了:

Use of uninitialized value $ARGV[0] in concatenation (.) or string at... 

解决方案:

问题的根源是Windows XP。启动perl的默认方法只传递第一个变量,即脚本名称。结果是$ ARGV [0]未初始化。

解决方法是编辑Windows注册表:

\HKEY_CLASSES_ROOT\Perl\shell\Open\command 

而且使该条目:

"C:\Perl\bin\perl.exe" %* 

结果是:

C:\whatever>perl argtest.pl 1 2 
Argument 1 ($ARGV[0]) is: 1, argument 2 ($ARGV[1]) is: 2. 

特别是由于大卫W¯¯谁指出我在正确的方向。

+0

你链接的教程不是很高的质量。它甚至没有“严格使用”。 – simbabque 2013-04-04 20:51:47

+1

幽默我:试试'argtest 1 2 3',看看会发生什么。 – 2013-04-04 20:52:30

+1

我尝试了你的代码(Mac OS X 10.7.5上的Perl 5.16.2;离你的平台很远),并且用'x.pl 1 2',我得到了'在串联(。)或字符串中使用未初始化的值'和输出 '参数0:1,参数1:2,参数2:.'我想知道你的Perl是否会误导你(尽管你的输出与'$ ARGV [0 ]未被初始化)。请记住,'$ 0'包含脚本的名称; '$ ARGV [0]'包含脚本的第一个参数的名称。 – 2013-04-04 20:54:41

回答

0

perl文件名不是参数数组的一部分。至少在测试我也必须删除ARGV[2]或传递三个参数,如argtest 1 2 3

+0

argtest的结果1 2 3:使用未初始化的值$ ARGV [0]连接(。)或C中的字符串:无变化。 – user2246544 2013-04-04 20:59:08

+0

DWIM基于草莓Perl,如果增加了任何东西。这很基础,我不明白它如何与DWIM相关。我并不在意perl的使用方式,但如果我更改为ActiveState,那么我会非常生气,而且没有什么不同。 – user2246544 2013-04-04 21:26:57

2

注意@ARGV在Perl是不是很喜欢在C. argv

       C   Perl 

Name of the program  argv[0]  $0 
1st argument    argv[1]  $ARGV[0] 
2nd argument    argv[2]  $ARGV[1] 
n-th argument    argv[n]  $ARGV[n-1] 

所以,如果你提供一个命令行参数到Perl脚本,它将在$ARGV[0]中找到。 $ARGV[1]将被初始化。

1

Windows有两种方式知道它应该使用Perl来执行程序。

  1. 命令行以perl可执行文件开头,要运行的脚本名称作为命令行参数提供。这也是它在Unix和其他环境中的工作原理。
  2. 您的系统将一个或多个扩展名(例如.pl,.pm和/或.cgi)与Perl应用程序相关联,当您使用其中一个扩展名键入文件名时,Windows将启动Perl,或者单击带有其中一个扩展名的文件Windows资源管理器中的扩展名。

你调用脚本仅仅作为

argtest 1 2 

perl argtest 1 2 
argtest.pl 1 2 

这让我觉得Perl是不是得看提到该文件的第一个应用程序而不是一个到argtest。也许有一个名为argtest.batargtest.exe的文件,它有让Perl运行你的Perl代码的任务。出于某种原因,该中间程序未将您提供的命令行参数传递给Perl应用程序。

提供这个中间文件的代码,我们可以帮助更多。


UPDATE:大卫W¯¯提出了第三个方式 - PATHEXT环境变量设置为inclue .pl文件和命令行调用argtest - 看他的答案。 然后,如果窗口的与.pl扩展名的文件关联被搞砸了,比方说,设置为只C:\Dwimperl\perl\bin\perl“而不是” C:\Dwimperl\perl\binperl %*“,那么OP会得到行为,他描述。

+0

用户在其中一个评论中说过,他尝试过'perl argtest.pl HELP!'并得到了相同的结果 – imran 2013-04-04 21:33:25

+0

是的,我是从“perl argtest.pl HELP!”运行它的。并得到了相同的结果。 – user2246544 2013-04-04 21:35:33

+0

实际上,你说运行'perl argtest.pl HELP!'的结果是'$ ARGV [1]'是未初始化的,而不是'$ ARGV [0]'。这实际上听起来像是按照它应有的方式工作。 – mob 2013-04-04 21:48:00

1

下载Cygwin并在Cygwin的测试代码(如果你是一个Unix主管,你会喜欢Cygwin,因为它给了你Windows机器上的Unix/Linux环境,没有它,我不会使用Windows)

Windows使用后缀来确定什么程序打开什么文件。你的Perl脚本叫argtest,argtest.batargtest.pl

在Windows上,确保所有Perl脚本都使用*.pl后缀,因此Windows将使用任何Perl参数来执行它们。 Windows不使用shebang

另一个可能的问题:在Windows XP中,我有Perl脚本有问题的参数,因为Windows有此作为执行字符串:

perl %1 

这将与我的脚本执行Perl程序,却忽略了参数。我必须将其更改为:

perl %* 

不幸的是,Windows Vista通过Windows 8改变了设置方式。但是,我有Windows 7并没有这个问题。由于目录名称中有空格,我确实在C:\Perl下安装了Perl,而不是C:\Program Files\Perl。我也安装了Strawberry Perl。

有一个特殊的Windows环境变量PATHEXT。这允许您键入foo而不是foo.pl。如果Windows无法看到如何执行文件,则Windows会通过%PATHEXT并尝试附加各种后缀,直到找到可用的后缀。您可能需要将.PL附加到该环境变量,因此您可以始终输入foo而不是foo.pl

+0

谢谢,我不知道'%PATHEXT%'。如果设置了OP的'PATHEXT',并且他的'.pl'文件关联只是'perl'而不是'perl%1'或'perl%*',那么这可以解释他的问题。 – mob 2013-04-04 23:48:05