とあるディレクトリ以下のファイルの情報を再帰的に収集するとして、シンボリックリンクがループしていた場合は
ループを検知して、処理をスキップしたいのですが、以下の方法で良いのでしょうか?
1. シンボリックリンクかつリンク先がディレクトリの場合、該当のシンボリックリンクのiノード番号を記録しておく
2. ファイル走査している過程で、再度同じiノード番号のシンボリックリンクを辿ろうとしたら、処理をスキップする
man symlinkには、ループの検知は「リンクを辿ってみて、リンクの最大数を超えたらループとみなす」というやり方が
書いてありました。上記方法でケアできないパターンが存在するのでしょうか?
http://www.google.co.jp/search?hl=ja&client=firefox-a&rls=org.mozilla%3Aja%3Aofficial&hs=8FP&q=symbolic+link+loop+detection&btnG=%E6%A4%9C%E7%B4%A2&lr=
> 上記方法でケアできないパターンが存在するのでしょうか?
いやむしろ,上記方法の方が,有向グラフのサイクル (向きのついたループ)
検出アルゴリズムとしては真当です.2つの方法を比較すると,
(1) 上記方法 (探索中の経路上の節点をすべて記録する方法) (a) サイクルを検出する正しい方法である. (ただし今回の場合は zzz_1980 さんの指摘を考慮する必要がある.) (b) 探索する経路の長さが事前にわからないので,動的メモリ管理が必要. (2) リンクをたどる回数を数え,上限値と比較する方法 (c) 上限値より長い,サイクルでない経路をサイクルと誤判定してしまう. (d) 短いサイクル (例えば自分自身へのリンク) であっても,必ず上限回数 だけリンクをたどらないと検出できない.誤判定を少なくしようとして 必要以上に上限を大きくすると時間がかかる. (e) 動的メモリ管理不要で,実装が超簡単.
symlink で (2) の方法を採用したのは,たぶん次のような理由でしょう.
inode だけを保持する方法では、
ファイルシステムをまたがってシンボリックリンクをはられたとき
期待する動作になりません。
(inodeはファイルシステム毎に振られるから)
inode とせっとでフルパスを控えておかないと、
同じシンボリックリンクかどうかわかりません。
find / -inum 2 -print とかやってみるとわかりますよ。
なるほど。たしかにファイルシステムにまたがるケースも考慮しておく必要がありそうです。
ありがとうございます。
> 上記方法でケアできないパターンが存在するのでしょうか?
いやむしろ,上記方法の方が,有向グラフのサイクル (向きのついたループ)
検出アルゴリズムとしては真当です.2つの方法を比較すると,
(1) 上記方法 (探索中の経路上の節点をすべて記録する方法) (a) サイクルを検出する正しい方法である. (ただし今回の場合は zzz_1980 さんの指摘を考慮する必要がある.) (b) 探索する経路の長さが事前にわからないので,動的メモリ管理が必要. (2) リンクをたどる回数を数え,上限値と比較する方法 (c) 上限値より長い,サイクルでない経路をサイクルと誤判定してしまう. (d) 短いサイクル (例えば自分自身へのリンク) であっても,必ず上限回数 だけリンクをたどらないと検出できない.誤判定を少なくしようとして 必要以上に上限を大きくすると時間がかかる. (e) 動的メモリ管理不要で,実装が超簡単.
symlink で (2) の方法を採用したのは,たぶん次のような理由でしょう.
なるほど。納得できました。
今回のケースではメモリについてはシビアではないので、(1)の方法を実施したいと思います。
ありがとうございます。
なるほど。納得できました。
今回のケースではメモリについてはシビアではないので、(1)の方法を実施したいと思います。
ありがとうございます。