次のディレクトリ ツリーがあります。
.
└── 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