Perl命令行:单引号和双引号在目录参数中的区别

5

我有困难理解在Windows中使用Perl的命令参数引用。 使用以下程序:

use strict;
use warnings;
use File::Find;
use File::Copy;

my $dir = shift;

die 'Usage: perl Folderize.pl <directory>' unless $dir;

die "$dir doesn't exist" unless -d $dir;

我根据目录使用单引号或双引号会得到不同的结果。如果我使用 'perl script.pl 'H:\Test!'' 调用它,会打印 "'H:\Test!' 不存在"。然而,如果我使用 'perl script.pl "H:\Test!"',就可以正常工作。这是为什么呢?


如果在Perl代码中使用双引号引用$dir会发生什么?祝你好运。 - shellter
如果在命令行上使用单引号,则“-d“$dir””仍然会失败。在这种情况下,不使用引号也可以工作,但只有因为路径中没有空格。 - Nate Glenn
你确定它显示的不是 H:\Test 存在吗?而是 H:\Test! 不存在? - Quentin
1
@Quentin 是的,感叹号在那里。这让你惊讶吗? - Nate Glenn
是的。引号只能在您的解释器中产生差异,因此如果它正在处理特殊字符,则应该从Perl错误消息中看到差异。 - Quentin
将来,如果你在Perl问题中包含了Perl标签,你会得到更多的关注。是的,这并不是真正的Perl问题,但任何在Windows上使用Perl的人都可能遇到这样的问题。很高兴你找到了一个好的解决方案。祝你好运! - shellter
4个回答

4
在命令行中,引号规则由shell而不是程序(perl)掌管。Unix shell的规则类似于Perl(双引号插值变量,单引号不会),但Windows“shell”有不同的规则。一些主要的区别包括:
- 单引号'不是特殊字符
``` C:\ dir > 'foo' ```
将创建一个名为'foo'的文件(引号将包含在文件名中)
- 双引号""插值环境变量,看起来像`%NAME%`,但它不会尝试将perl标量变量名称解释为环境变量
``` C:\ perl -e "print '%PATH'" ```
- 如果你忘记了,Windows shell会“关闭”你的引号
``` C:\ perl -e "print qq/Hello world/ Hello world ```
即使我忘记使用第二个双引号也可以工作。

1

这与Perl解释器无关。是shell解释命令及其参数。

例如,当您提供双引号参数"H:\Test!"时,shell将引号内的所有内容视为字符串的内容,并将传递给Perl解释器的内容是没有引号的字符串。

相比之下,当您提供'H:\Test!'时,shell将单引号作为字符串本身的一部分,并以这种方式将其传递给Perl解释器。


1
通过文件名来看,它可能不是bash,并且bash不会将单引号作为字符串的一部分传递。 - Quentin
我删掉了 shebang 行。我之前因为习惯加上了它,但是因为我在使用 Windows,所以不需要它。 - Nate Glenn

0
请考虑使用 Getopt::Long 而不是自己进行参数解析。

http://perldoc.perl.org/Getopt/Long.html

    use Getopt::Long;


    GetOptions
    (
        'dir=s' => \$dir,
    ) or die ("Couldnot process arguments");

在这种情况下,dir 将拥有目录,无论用户是否有。
    yourscript.pl -dir = foo
    yourscript.pl -dir  "foo"
    yourscript.pl -dir  foo

如果你这样做

    GetOptions
    (
        'dir=@s' => \@dir,
    ) or die ("Couldnot process arguments");

你将会得到一个普通的数组,其中包含所有目录

yourscript.pl -dir  foo -dir blah

OP 没有对开关进行任何解析,因此这里的 Getopt::Long 没有起到作用。 - Matt K
1
挺不错的。我想我会在某个地方使用它,但不会在这个脚本中使用,因为我只解析一个参数。 - Nate Glenn

0

由于您使用的是Windows操作系统,我假设您正在使用驱动器字母。那么您只需要接受,双引号是唯一的引号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接