непосредственная цель Perl - PullRequest
1 голос
/ 30 апреля 2019

Я ищу простой и правильный способ получения абсолютного пути непосредственной цели символической ссылки (не конечной цели), в perl .

Мой пример дерева:

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

Code1:

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

Cmd: ./script.pl ../dir1/link1

Результат: /tmp/perl_script_test/test/../dir1/../dir2/link2

Ожидается: /tmp/perl_script_test/dir2/link2

Я ищу абсолютный путь непосредственной цели символической ссылки без ../

Я пытался abs_path(), realpath(), но все они дают путь к конечной цели (file.txt)

Есть ли какая-нибудь встроенная функция, которая делает то, что я хочу сделать, мне нужно разделить путь и выполнить ручную конкатенацию?

-

Мохан Г

1 Ответ

1 голос
/ 30 апреля 2019

File :: Path's 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

Вы добавили к своему вопросу следующее:

Я ищу абсолютный путь непосредственной цели символической ссылки без ../

Вы не можете безопасно сделать это без разрешения символических ссылок. Например,

/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

(Вы могли бы заставить его работать, даже если первые две являются символическими ссылками, но это потребовало бы еще больше работы.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...