tkuchikiの日記

新ブログ https://blog.tkuchiki.net

find でディレクトリに symlink が含まれるときはパスの末尾に / をつけるか、-L をつける

$ tree -p /tmp/
/tmp/
├── [lrwxrwxrwx]  foobar -> /tmp/hoge
└── [drwxr-xr-x]  hoge
    ├── [-rw-r--r--]  hogege
    └── [-rw-r--r--]  hogehoge

2 directories, 2 files

というディレクトリ構成の時に、

$ find /tmp/hoge
/tmp/hoge
/tmp/hoge/hogege
/tmp/hoge/hogehoge

は、問題ないが、

$ find /tmp/foobar
/tmp/foobar

symlink の先が出力されない。
パスの末尾に / をつけるか、-L をつければ、symlink の先が出力される。
LinuxMac で検証したが、どちらも同じ結果だったので、
この件に関しては、LinuxBSD で find の挙動とオプションの違いは無いようだ。

$ find /tmp/foobar/
/tmp/foobar/
/tmp/foobar/hogege
/tmp/foobar/hogehoge

$ find -L /tmp/foobar
/tmp/foobar
/tmp/foobar/hogege
/tmp/foobar/hogehoge

symlink が含まれる可能性があるのならば、常にどちらかをつけておくと良いと思う。
ちゃんと調べていないが、つけていることによる弊害はないはず(問題があったら申し訳ないです...)。

※追記

@hnakamur2 さんからご指摘頂きましたが、Mac OS X (10.8.5, 10.9.2 で検証)だと、

$ find /tmp/foobar/
/tmp/foobar/
/tmp/foobar//hogege
/tmp/foobar//hogehoge

末尾に / をつけると、指定したディレクトリに / が2つ付いてしまう。
-L だとつかないので、find に渡したパスに / をつける実装になっているのだと思われる。
殆どの場合は問題無いと思われるが、パスを / で分解して処理するときにハマる可能性がある。
現実的ではないが、例を挙げる。
cut でファイルを抜き出そうとした場合、

# Linux
find /tmp/foobar/ | cut -d / -f 4

hogege
hogehoge

Linux では問題ないが、

# BSD
$ find /tmp/foobar/ | cut -d / -f 4


BSD だと抜き出す位置がずれてしまう(// の間になるので "" になる)。

したがって、LinuxBSD 両方で動かしたいスクリプトの場合は、
-L を指定するのが無難