7

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

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

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

4

3 回答 3

7

正如Chankey PathakMatthias 演示的dirname($0)那样,不会返回完整路径。

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

use FindBin qw($RealBin);

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

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

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

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

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

什么可能使两者都使用它更容易决定。


甚至更多,鉴于File::Basenamedirname的描述(最初的重点)

提供此功能是为了与 Unix shell 命令兼容,dirname(1)并继承了它的一些怪癖。尽管它有它的名字,但它并不总是像您期望的那样返回目录名称。为了安全起见,如果您想要路径的目录名称,请使用fileparse().

我宁愿去

use Cwd qw(abs_path);

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

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

于 2016-12-23T07:04:07.913 回答
4
  • 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
于 2016-12-23T06:43:38.353 回答
0

我不是下一个 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
于 2016-12-23T06:50:37.873 回答