當 /bin 是符號連結時,為什麼 $0=/bin/foo

當 /bin 是符號連結時,為什麼 $0=/bin/foo

我將 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在您的範例中)。

手冊頁:

透過遞歸地追蹤給定名稱的每個組件中的每個符號連結來規範化;除最後一個組件外的所有組件都必須存在

相關內容