【问题标题】:Perl command line: single vs. double quotes for directory argumentsPerl 命令行:目录参数的单引号和双引号
【发布时间】:2011-09-03 15:47:43
【问题描述】:

我无法理解 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 的使用会发生什么?祝你好运。
  • -d "$dir" 如果在命令行中使用了单引号,仍然会失败。在这种情况下,也可以不使用引号,但这只是因为路径没有空格。
  • 你确定它说H:\Test! 不存在吗?而不是H:\Test
  • @Quentin 是的,惊叹号就在那里。这让你感到惊讶吗?
  • 是的。引号应该只能在您的解释器中产生影响,因此如果它使用特殊字符执行某些操作,那么从 Perl 错误消息中应该可以看到差异。

标签: windows command-line quotes


【解决方案1】:

在命令行上,引用规则是 shell 的权限,而不是程序 (perl)。 Unix shell 的规则类似于 Perl 的规则(双引号插入变量,单引号不插入),但 Windows“shell”有不同的规则。一些主要区别是:

  • 单引号'不是特殊字符

    C:&gt;\ dir &gt; 'foo'

将创建一个名为 'foo' 的文件(引号将包含在文件名中)

  • "" 双引号插入看起来像%NAME% 的环境变量,但它不会尝试将 perl 标量变量名称解释为环境变量:

    C:&gt;\ perl -e "print '%PATH'"

  • 如果您忘记了,Windows shell 将为您“关闭”您的报价

    C:&gt;\ perl -e "print qq/Hello world/

    Hello world

即使我忘记使用第二个双引号,这仍然有效。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 使用那个文件名,它可能不是 bash,而且 bash 不会将单引号作为字符串的一部分传递。
    • 我删除了 shebang 行。我有那里是出于习惯,但我不需要它,因为我在 Windows 上工作。
    【解决方案3】:

    由于驱动器号,我假设您在 Windows(拇指)下工作。然后你必须接受,双引号是唯一的引号。

    【讨论】:

      【解决方案4】:

      请考虑使用 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 在这里什么也不做。
      • 很酷。我想我会在某个地方使用它,虽然不在这个脚本中,因为我只解析一个参数。
      猜你喜欢
      • 2013-02-16
      • 2020-07-25
      • 1970-01-01
      • 2013-12-05
      • 2020-04-06
      • 1970-01-01
      • 2014-01-21
      • 2011-10-06
      • 2011-10-20
      相关资源
      最近更新 更多