我试图向上遍历目录树,搜索给定的目录名,如果找到目录,我应该chdir
,否则会给出错误消息。例如:
use warnings;
use strict;
use Cwd qw(getcwd);
die "Base directory not found!" if (!gotoDir());
sub gotoDir {
my $baseDir = '.test';
my $curdir = getcwd();
while (1) {
return 1 if (-d $baseDir);
if (! chdir("..")) {
chdir($curdir);
return 0;
}
}
}
问题是chdir
超越root时不会失败,所以如果找不到.test
,上面的程序会进入无限循环。
当然,我可以测试/
,因为我在Linux上,但我想以独立于系统的方式进行此操作。
答案 0 :(得分:3)
正如@Gnouc所回答的那样,File::Spec
模块具有根目录的可移植表示及其rootdir
方法。
这就是我写goto_dir
子程序的方法。请注意,大写字母通常保留用于Package::Names
等全局标识符。
我认为最好将您要搜索的目录作为参数传递给子例程,以使其更通用。我也写了它,以便子程序对chdir
目录执行.test
如果找到了,这就是你想要的,但不是你自己的解决方案试图做的。
最后,由于可移植性很重要,我使用File::Spec->updir
代替文字'..'
来引用当前目录的父级。
#!/usr/bin/env perl
use strict;
use warnings;
use Cwd 'cwd';
use File::Spec;
goto_dir('.test') or die 'Base directory not found!';
sub goto_dir {
my ($base_dir) = @_;
my $original_dir = cwd;
while () {
if (-d $base_dir) {
chdir $base_dir;
return 1;
}
elsif (cwd eq File::Spec->rootdir) {
chdir $original_dir;
return 0;
}
else {
chdir File::Spec->updir;
}
}
}
答案 1 :(得分:1)
您可以使用File::Spec获取根目录:
$ perl -MFile::Spec -E 'say File::Spec->rootdir()'
/
答案 2 :(得分:1)
File::Spec
非常适合获取根目录 的内容,但是用于测试给定目录是否是不是那么容易。为此,您可能希望使用stat
并比较dev
和ino
字段是否相等:
use File::stat;
my $rootstat = stat(File::Spec->rootdir);
...
my $thisstat = stat($dir);
if( $thisstat->dev == $rootstat->dev and $thisstat->ino == $rootstat->ino ) {
say "This is the root directory";
}
这避免了目录路径的字符串格式化形式的问题,例如,您可能拥有路径../../../../../..
。