我需要让Perl从Linux路径中删除相对路径组件。我发现了几个几乎可以做我想要的功能,但是:
File::Spec->rel2abs
做得太少了。它没有正确地将“..”解析为目录。
Cwd::realpath
做得太多了。它解析了路径中的所有符号链接,这是我不想要的。
也许说明我希望这个函数如何表现的最好方法是发布一个bash日志,其中FixPath是一个假设命令,提供所需的输出:
'/tmp/test'$ mkdir -p a/b/c1 a/b/c2
'/tmp/test'$ cd a
'/tmp/test/a'$ ln -s b link
'/tmp/test/a'$ ls
b link
'/tmp/test/a'$ cd b
'/tmp/test/a/b'$ ls
c1 c2
'/tmp/test/a/b'$ FixPath . # rel2abs works here
===> /tmp/test/a/b
'/tmp/test/a/b'$ FixPath .. # realpath works here
===> /tmp/test/a
'/tmp/test/a/b'$ FixPath c1 # rel2abs works here
===> /tmp/test/a/b/c1
'/tmp/test/a/b'$ FixPath ../b # realpath works here
===> /tmp/test/a/b
'/tmp/test/a/b'$ FixPath ../link/c1 # neither one works here
===> /tmp/test/a/link/c1
'/tmp/test/a/b'$ FixPath missing # should work for nonexistent files
===> /tmp/test/a/b/missing
答案 0 :(得分:-1)
好的,这就是我想出的:
sub mangle_path {
# NOT PORTABLE
# Attempt to remove relative components from a path - can return
# incorrect results for paths like ../some_symlink/.. etc.
my $path = shift;
$path = getcwd . "/$path" if '/' ne substr $path, 0, 1;
my @dirs = ();
for(split '/', $path) {
pop @dirs, next if $_ eq '..';
push @dirs, $_ unless $_ eq '.' or $_ eq '';
}
return '/' . join '/', @dirs;
}
我知道这可能是不安全和无效的,但是这个例程的任何输入都将来自我的命令行,它为我解决了一些棘手的用例。