• 作成:

updatedbをsystemdのタイマーで自動的に実行してファイル検索locateの情報を最新に保つ

Unixにはlocateというプログラムがあります.

これはコンピュータ内部のファイルを検索するためのプログラムであり, findよりも圧倒的に高速です.

検索キーワードには正規表現を使うことができます.

helm-for-fileshelm-locateにも使われています.

Emacsのhelm-for-filesでnintendoと検索している様子

なぜlocateがfindよりも高速なのか. locateはファイルのインデックスを参照するから速いのです.

しかしlocateにはだからこその弱点があります. locateはupdatedbコマンドでインデックスを作成しないと検索ができません. また, updatedbを実行した後に作られたファイルは検索結果に出てきません.

私はこの問題を解決するためにたまにupdatedbを実行していたのですが, だんだん面倒になってきました.

今使っているデスクトップPCはある程度強力なスペックを持っています. また, 今はラップトップを充電せずに使うことはほぼ無いので, バッテリーを気にする必要はありません. というわけで自動化しました.

まず/etc/systemd/system/updatedb.serviceに以下のファイルを置きます.

[Service]
Type=oneshot
Nice=19
ExecStart=/usr/bin/updatedb

そして/etc/systemd/system/updatedb.timerに以下のファイルを置きます.

[Timer]
OnBootSec=15min
OnUnitActiveSec=30min

[Install]
WantedBy=timers.target

そしてsudo systemctl enable updatedb.timerします.

これでこのコンピュータでは30分に1回updatedbを実行するようになりました.

ただ, ファイルを作成した瞬間に即座にインデックスを更新してくれないのは残念ですね.

Trackerなどでは行ってくれるのでしょうか? Gnome Shellを使っていた頃はTrackerも使っていたのですが, あまりのインデックス作成の遅さとバッテリーの浪費に使うのをやめてしまいました. デスクトップ環境に依存しないインクリメント全文検索を行ってくれるソフトウェアを開発したら需要がある?

locateに関する余談

キャッシュを除去

私はキャッシュディレクトリなどのノイズを除去するために現在以下のようなupdatedb.confを設定しています.

# /etc/updatedb.conf: config file for slocate
# $Id: updatedb.conf,v 1.6 2014/05/05 06:42:03 polynomial-c Exp $

# This file sets variables that are used by updatedb.
# For more info, see the updatedb.conf(5) manpage.

# Filesystems that are pruned from updatedb database
PRUNEFS="afs anon_inodefs auto autofs bdev binfmt binfmt_misc cgroup cifs coda configfs cramfs cpuset debugfs devfs devpts devtmpfs ecryptfs eventpollfs exofs futexfs ftpfs fuse fusectl gfs gfs2 hostfs hugetlbfs inotifyfs iso9660 jffs2 lustre misc mqueue ncpfs nfs NFS nfs4 nfsd nnpfs ocfs ocfs2 pipefs proc ramfs rpc_pipefs securityfs selinuxfs sfs shfs smbfs sockfs spufs sshfs subfs supermount sysfs tmpfs ubifs udf usbfs vboxsf vperfctrfs"

# Paths which are pruned from updatedb database
PRUNEPATHS="/tmp /var/tmp /var/cache /var/db/pkg /var/lock /var/run /var/spool"

# Folder names that are pruned from updatedb database
PRUNENAMES=".Trash .cache .cargo .git .hg .stack .stack-work .svn CVS Cache Trash __pycache__ appcache cache cached dist file-backup htmlcache metadata node_modules steam-runtime texmf-dist tmp undo-tree yesod-devel"

# Skip bind mounts.
PRUNE_BIND_MOUNTS="yes"

カレントディレクトリ以下を検索

findのように, locateでもカレントディレクトリ以下を検索したい時は多々あります.

以下のようなzsh関数で実現可能です.

locate-current-dir() {
    locate --ignore-case --regex "^$(pwd).*$1.*" ${@[2, -1]}
}