為什麼 tree 指令將符號連結標記為遞迴?

為什麼 tree 指令將符號連結標記為遞迴?

我有以下目錄樹:

.
└── aaa
    └── bbb
        └── ccc

並建立符號連結:

ln -s ~/test/aaa/bbb slink

之後我運行樹命令:

tree -l

並看到

.
├── aaa
│   └── bbb
│       └── ccc
└── slink -> /home/kaa/test/aaa/bbb  [recursive, not followed]

為什麼slink被標記為遞迴?這是一個錯誤還是我誤解了什麼?

答案1

您使用了以下-l選項:

如果符號連結指向目錄,則遵循符號鏈接,就像它們是目錄一樣。偵測到會導致遞歸的符號連結時會避免。

現在,它印出此警告的原因並不是它會實際上遞迴.我們可以清楚地看到它只是bbb/ccc再次列出樹。

對應的代碼是這裡, 順便一提。如果在哈希表(用saveino和填充的哈希表)中找到符號連結指向的目錄的 inode 號findino,它將簡單地跳過它。

答案2

我認為文檔不準確。文件說

符號連結將導致遞迴被發現時會避開

但它應該說類似的話

符號連結將導致已造訪過的目錄沒有被關注

錯誤訊息的位置tree.c函數findinohash.c

tree -l記住訪問過的目錄,並且只下降到連結尚未訪問其目標:

( mkdir test1 && cd test1 && mkdir -p a/b && ln -s a link && tree -l; )
.
├── a
│   └── b
└── link -> a  [recursive, not followed]

請注意,忽略已造訪的目錄僅適用於連結真實的目錄總是被存取。這意味著遍歷的順序很重要。以反向字母順序 ( ) 遍歷連結後的完全相同的樹-r,因為它在其目標尚未訪問時訪問該連結。

( cd test1 && tree -r -l; )
.
├── link -> a
│   └── b
└── a
    └── b

這裡還有兩種重現此行為的替代方法:

忽略( -I)目錄a/,這樣存取連結時就不會存取該目錄:

( cd test1 && tree -l -I a; )
.
└── link -> a
    └── b

命名目錄和鏈接,以便自然地首先訪問鏈接:

( mkdir test2 && cd test2 && mkdir -p x/y && ln -s x link && tree -l; )
.
├── link -> x
│   └── y
└── x
    └── y

相關內容