我發現Tcl的[file normalize $path]
與C中調用所使用的路徑解析之間存在差異如open()
和 realpath()
。
它是圍繞使用符號鏈接緊接着..
。
的設置:給定這個目錄結構(注意sidedir_link
是一個鏈接到一個 不同目錄):
/tmp/fileA.txt
/tmp/sidedir/fileA.txt
/tmp/subdir/fileA.txt
/tmp/subdir/sidedir_link -> /tmp/sidedir
當前目錄是/tmp/subdir
,我已經創建的命令 utils::realpath
是一個Tcl請撥打電話realpath()
<stdlib.h>
。
這是抄本。前兩個電話顯示如何解決符號 鏈接。最後兩個顯示在處理 ..
時行爲上的差異,它緊跟在符號鏈接之後。
wish% file normalize sidedir_link/fileA.txt
/tmp/sidedir/fileA.txt
wish% ::utils::realpath sidedir_link/fileA.txt
/tmp/sidedir/fileA.txt
wish% file normalize sidedir_link/../fileA.txt
/tmp/subdir/fileA.txt
wish% ::utils::realpath sidedir_link/../fileA.txt
/tmp/fileA.txt
注:不同的是/tmp/subdir/fileA.txt
與/tmp/fileA.txt
。
具體地說,[file normalize $path]
出現通過除去路徑的前述部分,以詞法解析..
,而C實際上 調用解決符號鏈接和然後應用..
。如果符號鏈接 是到/some/location/far/far/away
,解析的路徑將是 /some/location/far/far/fileA.txt
。
我找不到在Tcl文檔的這個任何提及,維基,或者在錯誤 跟蹤系統。
那麼,這是一個Tcl錯誤?一個C庫的錯誤?預期的行爲?
我使用Tcl 8.4.9和紅帽6(是的,有點落伍了......)
注:我可以重現的Tcl 8.6.1
相同的行爲究其原因,這是重要的是,的Tcl/Tk GUI的指示文件存在(因爲它使用了file
命令),但在後端實際上是打開使用C庫調用open()
文件,運行失敗(因爲路徑是不同的,並不存在)。
這看起來像是與Tcl虛擬文件系統支持的交互。理論上,路徑可以指向一個web服務器路徑,'realpath()'在那裏不起作用,所以代碼必須從文本表示中起作用。事實上,Tk的開放對話甚至可能會向您顯示數據庫BLOB中的文件,並且您的C庫'open()'調用也會失敗。所以這可能是預期的行爲,但也許是一個錯誤。在處理角落案件時,在代碼的這一部分發現了各種各樣的錯誤,所以不知道如何分類這個錯誤。 – schlenk
@schlenk我猜你會扭曲這樣的說法,只有'文件normalize'實際上做正確的事與符號鏈接(使用的具體實施Unix文件系統),當你不使用'..'。所以,它可以類似地使用具體實現來解決'..'。 例如,我可以有一個數據庫BLOB其中'..'是一個有效的文件名(而不是指父目錄),在這種情況下,Tcl的實施似乎從來沒有工作... –
不知道你知道Tcl vfs系統,所以blob示例可能不好。但是爲了回到這一點,在路徑中有一些關於'file normalize'和'..'的測試(見https://core.tcl.tk/tcl/artifact/中的測試'filesystem-1。*' 0a3fce191778e80a)。我沒有在那裏看到你的確切情況,所以也許它是一個錯過的角落案例。 – schlenk