【问题标题】:Changing to a directory and then getcwd()切换到一个目录,然后 getcwd()
【发布时间】:2017-05-08 20:38:56
【问题描述】:

我的许多同事在他们的 BEGIN 块中使用以下命令。

$scriptDir = dirname($0);
chdir($scriptDir);
$scriptDir =  getcwd();

我环顾四周,不禁认为第三行,即$scriptDir = getcwd(); 是多余的。因为我们已经有了来自$scriptDir = dirname($0); 的脚本目录。我在这里遗漏了什么吗?

【问题讨论】:

  • 如下图,use FindBin qw( $RealBin );不要换目录。 @ARGV 中列出的文件是相对于 pwd,而不是 $RealBin

标签: perl dirname getcwd


【解决方案1】:

dirname($0) 不返回完整路径,如 Chankey PathakMatthias 演示。

我想补充一点,还有其他方法。例如,您可以使用FindBin(也是核心)

use FindBin qw($RealBin);

BEGIN: {
    my ($scriptDir) = $RealBin;
    chdir $scriptDir             or die "Can't change to $scriptDir: $!";
};

$RealBin 与您显示的相同,只是它是已解析链接的完整路径。

chdir 可能会失败,感谢ikegami 的评论。在这种情况下,会返回 false 并且上面的代码会失效,请根据需要进行调整。请注意,被质疑的第三行与此无关。

这个模块也常用于带有lib pragma 的库的相对路径,例如

use lib "$RealBin/../lib";

这可能会让你更容易决定同时使用它。


考虑到来自File::Basenamedirname 描述(原始重点),甚至更多

提供此函数是为了与 Unix shell 命令dirname(1) 兼容,并继承了它的一些怪癖。尽管它的名称是 NOT,但它总是如您所料地返回目录名称。为了安全起见,如果您想要路径的目录名称,请使用 fileparse()

我宁愿去

use Cwd qw(abs_path);

BEGIN: {
    my ($scriptDir) = abs_path(__FILE__) =~ m|(.*)/|;
    chdir $scriptDir             
        or die "Can't change to $scriptDir: $!";
};

使用abs_path 的位置是因为__FILE__ 本身可能无法提供完整路径。正则表达式贪婪地将所有内容提取到最后一个 /,即脚本目录的完整路径。

【讨论】:

    【解决方案2】:
    • getcwd - 返回当前工作目录
    • chdir - 将工作目录更改为 EXPR

    下面的例子很好地解释了它。

    #!/usr/bin/perl
    use strict;
    use warnings;
    use File::Basename;
    use Cwd;
    
    my $scriptDir = dirname($0);
    chdir($scriptDir);
    print "First: $scriptDir\n";
    $scriptDir =  getcwd();
    print "Second: $scriptDir\n";
    

    输出:

    chankeypathak@stackoverflow:~/Desktop$ perl test.pl 
    First: .
    Second: /home/chankeypathak/Desktop
    

    【讨论】:

      【解决方案3】:

      我不是下一个 perl 贩子,但我尝试用一​​个小脚本来执行你提供的代码:

      #!/usr/bin/perl
      # 
      
      use strict;
      use File::Basename;
      use Cwd;
      
      BEGIN {
        my $scriptDir = dirname($0);
        print "scriptDir = $scriptDir\r\n";
        chdir($scriptDir);
        $scriptDir =  getcwd();
        print "scriptDir = $scriptDir\r\n";
      }
      

      这就是结果:

      map@host:~/perltest> ./script.pl 
      scriptDir = .
      scriptDir = /home/map/perltest
      map@host:~/perltest> 
      

      看起来 dirname 和 getcwd 在这种情况下有所不同。但是,如果在路径中找到 scrip.pl,则没有区别:

      map@host:~> cp script.pl ~/bin
      map@host:~> cd
      map@host:~> script.pl
      scriptDir = /home/map/bin
      scriptDir = /home/map/bin
      map@host:~> rm ~/bin
      

      【讨论】:

        猜你喜欢
        • 2011-01-25
        • 2011-02-16
        • 2019-11-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-06-25
        相关资源
        最近更新 更多