なぜ tree コマンドはシンボリック リンクを再帰としてマークするのですか?

なぜ tree コマンドはシンボリック リンクを再帰としてマークするのですか?

次のディレクトリ ツリーがあります。

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

シンボリックリンクを作成します:

ln -s ~/test/aaa/bbb slink

この後、tree コマンドを実行します:

tree -l

そして見る

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

なぜ slink が再帰的としてマークされているのでしょうか? これはバグでしょうか、それとも私が何かを誤解しているのでしょうか?

答え1

使用した-lオプション:

シンボリック リンクがディレクトリを指している場合は、ディレクトリであるかのようにシンボリック リンクをたどります。再帰が発生するシンボリック リンクが検出された場合は、そのリンクは回避されます。

さて、この警告が表示される理由は、実は再帰。単にツリーを再度リストするだけであることがはっきりとわかりますbbb/ccc

それぞれのコードはここちなみに、シンボリックリンクが指すディレクトリの inode 番号がハッシュ テーブル (および が入力されているテーブルsaveino)で見つかった場合はfindino、単にスキップされます。

答え2

ドキュメントは不正確だと思います。ドキュメントにはこう書かれています

シンボリックリンクは再帰検出された場合は回避される

しかし、次のように言うべきです

シンボリックリンクはすでに訪問したディレクトリ従わない

見るエラーメッセージの場所tree.cそして 機能findinoするhash.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

この動作を再現するための 2 つの代替手段を次に示します。

リンクにアクセスしたときにアクセスされないように、-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

関連情報