将参数传递给脚本,得到:“使用未初始化的值$ ARGV [0]”
问题: 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¯¯谁指出我在正确的方向。
perl
文件名不是参数数组的一部分。至少在测试我也必须删除ARGV[2]
或传递三个参数,如argtest 1 2 3
argtest的结果1 2 3:使用未初始化的值$ ARGV [0]连接(。)或C中的字符串:无变化。 – user2246544 2013-04-04 20:59:08
DWIM基于草莓Perl,如果增加了任何东西。这很基础,我不明白它如何与DWIM相关。我并不在意perl的使用方式,但如果我更改为ActiveState,那么我会非常生气,而且没有什么不同。 – user2246544 2013-04-04 21:26:57
注意@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]
将被初始化。
Windows有两种方式知道它应该使用Perl来执行程序。
- 命令行以perl可执行文件开头,要运行的脚本名称作为命令行参数提供。这也是它在Unix和其他环境中的工作原理。
- 您的系统将一个或多个扩展名(例如
.pl
,.pm
和/或.cgi
)与Perl应用程序相关联,当您使用其中一个扩展名键入文件名时,Windows将启动Perl,或者单击带有其中一个扩展名的文件Windows资源管理器中的扩展名。
你调用脚本仅仅作为
argtest 1 2
和
perl argtest 1 2
argtest.pl 1 2
这让我觉得Perl是不是得看提到该文件的第一个应用程序而不是一个到argtest
。也许有一个名为argtest.bat
或argtest.exe
的文件,它有让Perl运行你的Perl代码的任务。出于某种原因,该中间程序未将您提供的命令行参数传递给Perl应用程序。
提供这个中间文件的代码,我们可以帮助更多。
UPDATE:大卫W¯¯提出了第三个方式 - PATHEXT
环境变量设置为inclue .pl
文件和命令行调用argtest
- 看他的答案。 然后,如果窗口的与.pl
扩展名的文件关联被搞砸了,比方说,设置为只C:\Dwimperl\perl\bin\perl
“而不是” C:\Dwimperl\perl\binperl %*
“,那么OP会得到行为,他描述。
用户在其中一个评论中说过,他尝试过'perl argtest.pl HELP!'并得到了相同的结果 – imran 2013-04-04 21:33:25
是的,我是从“perl argtest.pl HELP!”运行它的。并得到了相同的结果。 – user2246544 2013-04-04 21:35:33
实际上,你说运行'perl argtest.pl HELP!'的结果是'$ ARGV [1]'是未初始化的,而不是'$ ARGV [0]'。这实际上听起来像是按照它应有的方式工作。 – mob 2013-04-04 21:48:00
下载Cygwin并在Cygwin的测试代码(如果你是一个Unix主管,你会喜欢Cygwin,因为它给了你Windows机器上的Unix/Linux环境,没有它,我不会使用Windows)
Windows使用后缀来确定什么程序打开什么文件。你的Perl脚本叫argtest
,argtest.bat
或argtest.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
。
谢谢,我不知道'%PATHEXT%'。如果设置了OP的'PATHEXT',并且他的'.pl'文件关联只是'perl'而不是'perl%1'或'perl%*',那么这可以解释他的问题。 – mob 2013-04-04 23:48:05
你链接的教程不是很高的质量。它甚至没有“严格使用”。 – simbabque 2013-04-04 20:51:47
幽默我:试试'argtest 1 2 3',看看会发生什么。 – 2013-04-04 20:52:30
我尝试了你的代码(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