CTOになるまで続けるブログ

My daily personal tech notes

GNU locate

GNU locate は、システムに存在するあらゆるファイルに対して、 ファイルのフルパスを対象としたパターンマッチング検索を行うためのツールである。 検索はあらかじめ作成しておいたデータベースを利用するため、非常に高速である。 データベースの圧縮には、インクリメンタルエンコーディングが用いられている。

検索アルゴリズムのデフォルトは、部分一致検索である。 検索文字列をフルパスの一部に含むファイルをリストアップする。 一方、検索文字列にメタキャラクタが含まれる場合は、パターンマッチングに切り替わる。 対応するメタキャラクタは * と ? と [] で、シェルで馴染み深い glob が実装されている。

GNU locate は、locate コマンドと updatedb コマンドの2つで構成される。 検索には locate コマンド、データベースの作成および更新には updatedb コマンドを用いる。 GNU locate は、一時ディレクトリとネットワークディレクトリを除いた全てのファイルを検索対象とする。 明示的に検索範囲を指定するには、updatedb のコマンドオプションを利用するとよい。 それ以外には、チューニングに関するパラメータ(例えば、データベースの圧縮率の変更など)は特に存在しない。

使用上の注意としては、検索結果はデータベースを更新したタイミングに依存するということである。 データベース更新以降に作成されたファイルは、検索してもヒットしない。 逆に、データベース更新以降に削除されたファイルが、検索するとヒットしてしまう。 この問題には、locate コマンドの --exiting オプションが有効である。 --existing オプションを与えることで、locate コマンドは検索処理に存在確認を組み合わせる。 これによって、存在しないファイルは検索結果として表示されない。 ただし、検索結果が多い時には存在確認がボトルネックとなって、重くなってしまうので注意すること。

インストール方法について触れておく。 CentOS 7 であれば、yum インストールが簡単である。 ただし、登録されているのは mlocate パッケージなので、パッケージ名もそのように指定すること。 mlocate パッケージは、GNU locate に機能拡張を施したものである。 具体的には、前回の結果をキャッシュとして利用することで、データベース更新の高速化を実現している。 データベースの更新は夜間に定期実行するのが一般的であるが、 mlocate のように効率化された実装であれば hourly でも十分機能するだろう。

macOS であれば、brew インストールが簡単である。 findutils フォーミュラに組み込まれているので、フォーミュラ名にはこれを指定すること。 しかし findutils フォーミュラで提供されるのは、GNU locate ではなく BSD locate である。 注意点は、updatedb コマンドが locate.updadb と違っていることである。 また、コマンドのインストール先が PATH の通っていない /usr/libexec であることである。 不便であれば、スタートアップスクリプトでエイリアスを作るとよい。

alias updatedb='sudo /usr/libexec/locate.updatedb'

最後に、man の情報は一部古いようである。 コマンドに対応する man を見てみると、言及されていないコマンドオプションが目立つ。 正確な情報が知りたい場合は、GNU findutils のドキュメントを参考にするとよい。 この記事の内容も、もともとは man の情報を出典にしていたが、 途中からそれに気づいて GNU findutils のドキュメントの内容を元に書き直した。 なお、GNU findutils は、find や locate といったファイル検索コマンドを管理する GNU プロジェクトである。 GNU locate はどこかのタイミングで、このプロジェクトに統合されたようだ。

www.gnu.org