2010-04-27 43 views
0

我需要讓Perl從Linux路徑中移除相對路徑組件。我發現幾乎幾乎所有我想要的功能,但是:如何刪除相對路徑組件,但在Perl中只保留符號鏈接?

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 
+3

我很確定你不會準確地找到你需要的東西。爲什麼你需要單獨的鏈接?另外,你將如何處理符號鏈接,其中包含./../../bin/twiddle/../其中,實際上,twiddle是一個符號鏈接,可以/任意/其他/路徑(或任意/路徑/從/在這裏)。另外,你希望在符號鏈接路徑中使用循環,或者其他類似的操作。 – 2010-04-27 01:36:21

+0

我很滿意這種情況下的解決方案(例如'./../../ bin/twiddle /../ there'成爲'/ tmp/test/bin/there')。它不應該永遠需要讀取符號鏈接。如果這樣的功能不存在(我開始明白爲什麼...),那麼我會寫它。 – jnylen 2010-04-27 01:40:44

+0

如果您只是想將「foo /../ bar」翻譯爲「bar」,那就這麼做 - 但這不是一般的文件系統操作;因此缺乏支持。 – jrockway 2010-04-27 01:43:40

回答

-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; 
} 

我知道這可能是不安全的,無效的,但任何輸入到該程序將來自我在命令行上,它解決了幾個棘手的使用情況對我來說。

+1

使用File :: Spec的catfile以便攜方式連接路徑。 – 2010-04-27 18:53:41

+0

現在我不在乎這個應用程序的可移植性。如果我改變了主意,我已經在代碼中標記了我知道需要更改的地方。 – jnylen 2010-04-28 15:10:41

相關問題