perl symlink即时目标

时间:2019-04-30 00:33:22

标签: perl symlink-traversal

我正在寻找一种简单且正确的方法,以 perl 来获取 symlink即时目标的绝对路径(而非最终目标)。 / p>

我的示例树:

|-- dir1
|   |-- link1 -> ../dir2/link2
|-- dir2
|   `-- link2 -> ../dir3/file.txt
|-- dir3
|   `-- file.txt
`-- test
    `-- script.pl

代码1:

my $link = dirname($ARGV[0]).'/'.readlink($ARGV[0]); 
print rel2abs($link), "\n";

命令:./script.pl ../dir1/link1

结果:/tmp/perl_script_test/test/../dir1/../dir2/link2

预期:/tmp/perl_script_test/dir2/link2

我正在寻找没有../

的symlink立即目标的绝对路径

我尝试了abs_path()realpath(),但它们都为最终目标(file.txt)提供了路径

是否有任何内置函数可以执行我想做的事情,我需要分割路径并进行手动串联?

-

Mohan G

1 个答案:

答案 0 :(得分:1)

File :: Path的absolute不执行任何文件系统检查。

use File::Path qw( file );

my $link_qfn = file(...);

my $link_dir_qfn = $link_qfn->dir;
my $target_qfn   = $link_dir_qfn->file(readlink($link_qfn));
my $target_fqfn  = $target_qfn->absolute;

say $target_fqfn;

假设CWD为/tmp/perl_script_test/test

$link_qfn     ../dir1/link1
$link_dir_qfn ../dir1
$target_qfn   ../dir1/../dir2/link2
$target_fqfn  /tmp/perl_script_test/test/../dir1/../dir2/link2

假设CWD为/tmp/perl_script_test

$link_qfn     dir1/link1
$link_dir_qfn dir1
$target_qfn   dir1/../dir2/link2
$target_fqfn  /tmp/perl_script_test/dir1/../dir2/link2

您已在问题中添加了以下内容:

  

我正在寻找没有../

的symlink立即目标的绝对路径

如果不解决符号链接,就无法安全地做到这一点。例如,

/tmp/perl_script_test/dir1/../dir2/link2

不一定等于

/tmp/perl_script_test/dir2/link2

因为

/tmp/perl_script_test/dir1 

可能是符号链接。


以下内容可能对您足够:

use Cwd        qw( real_path );
use File::Path qw( dir file );

my $link_qfn = file(...);

my $link_dir_qfn    = $link_qfn->dir;
my $target_qfn      = $link_dir_qfn->file(readlink($link_qfn));
my $target_fn       = $target_qfn->basename;
my $target_dir_qfn  = $target_qfn->dir;
my $target_dir_fqfn = dir(real_path($target_dir_qfn));
my $target_fqfn     = $target_dir_fqfn->file($target_fn);

say $target_fqfn;

假设CWD为/tmp/perl_script_test/test

$link_qfn        ../dir1/link1
$link_dir_qfn    ../dir1
$target_qfn      ../dir1/../dir2/link2
$target_fn       link2
$target_dir_qfn  ../dir1/../dir2
$target_dir_fqfn /tmp/perl_script_test/dir2
$target_fqfn     /tmp/perl_script_test/dir2/link2

仅当以下都不是符号链接时,您才会获得上面的输出:

/tmp
/tmp/perl_script_test
/tmp/perl_script_test/test
/tmp/perl_script_test/dir1
/tmp/perl_script_test/dir2

(即使前两个是符号链接,您也可以使它工作,但这将花费更多的工作。)