
我將 bash 腳本安裝到了/usr/bin/app.sh
和/usr/bin/lib.sh
app.sh
包括
source "/usr/bin/lib.sh"
並lib.sh
包括
if [ "/usr/bin/app.sh" == "$0"] ...
app.sh
當我從 shell運行時,此測試失敗,因為$0
實際上是/bin/app.sh
.在檔案系統上,/bin
是一個符號連結/usr/bin
lib.sh
確定它是否被包含app.sh
(而不是被other-app.sh
)以不會被環境欺騙的最佳方法是什麼?我以為沒有符號連結的絕對路徑就可以完成這項工作,但顯然不是。
答案1
要檢查兩個檔案是否相同,需要檢查索引(inode)號,顯示為:
stat -L -c %i FilePath
所以你的支票現在變成:
if [ $(stat -L -c %i "/usr/bin/app.sh") == $(stat -L -c %i "$0") ] ...
無論目錄路徑中是否有任何鏈接,甚至是到文件本身的符號鏈接或硬鏈接,這都有效。
為了嚴格準確(感謝 @ilkkachu 指出了這一點),兩個具有相同名稱的不同文件在兩個不同的文件系統上具有相同的 inode 的可能性很小。為了避免這種情況,請在比較中包含設備編號:
if [ $(stat -L -c %d:%i "/usr/bin/app.sh") == $(stat -L -c %d:%i "$0") ] ...
答案2
readlink -f /path/to/whatever
將告訴您規範路徑(將/usr/bin/app.sh
在您的範例中)。
從手冊頁:
透過遞歸地追蹤給定名稱的每個組件中的每個符號連結來規範化;除最後一個組件外的所有組件都必須存在