我的许多同事在他们的 BEGIN 块中使用以下命令。
$scriptDir = dirname($0);
chdir($scriptDir);
$scriptDir = getcwd();
我环顾四周,不禁认为第三行 ie$scriptDir = getcwd();
是多余的。因为我们已经有了来自的$scriptDir = dirname($0);
scriptdir。我在这里遗漏了什么吗?
正如Chankey Pathak和Matthias
演示的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__
它本身可能无法提供完整路径。正则表达式贪婪地将所有内容提取到最后一个/
,即脚本目录的完整路径。
下面的例子很好地解释了它。
#!/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
我不是下一个 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