Categories
SysOps

How to quickly and securely search for files

Using find command is not always the fastest way to search for specific files. The better method is to use mlocate utility, which uses its own file database and provides only user-accessible results.

Basic mlocate usage

File search

By default, the command will match the whole path name against the specified patterns.

$ mlocate xserver-xorg-video-all
/usr/share/doc/xserver-xorg-video-all
/usr/share/doc/xserver-xorg-video-all/changelog.gz
/usr/share/doc/xserver-xorg-video-all/copyright
/var/lib/dpkg/info/xserver-xorg-video-all.list
/var/lib/dpkg/info/xserver-xorg-video-all.md5sums

Use -b parameter to match only base names against the specified patterns.

$ mlocate -b xserver-xorg-video-all
/usr/share/doc/xserver-xorg-video-all
/var/lib/dpkg/info/xserver-xorg-video-all.list
/var/lib/dpkg/info/xserver-xorg-video-all.md5sums

The -A parameter will print file names that match all patterns instead of one of them.

$ mlocate -b xserver-xorg-video-all md5
/boot/grub/i386-pc/gcry_md5.mod
/usr/bin/md5sum
/usr/bin/md5sum.textutils
[..]
/var/lib/dpkg/info/xserver-xorg-video-all.md5sums
[..]
$ mlocate -A -b xserver-xorg-video-all md5
/var/lib/dpkg/info/xserver-xorg-video-all.md5sums

Use -i parameter to ignore the case.

$ mlocate -i -A -b xserver-xorg-video-all MD5
/var/lib/dpkg/info/xserver-xorg-video-all.md5sums

Use -r parameter to define REGEXP instead of the pattern.

$ mlocate -b -r "xserver-xorg-input-[a-z]\{5\}.md[5][a-z]*$"
/var/lib/dpkg/info/xserver-xorg-input-evdev.md5sums
/var/lib/dpkg/info/xserver-xorg-input-mouse.md5sums
/var/lib/dpkg/info/xserver-xorg-input-wacom.md5sums

Count matched file names

Use -c parameter to count the number of matched file names.

$ mlocate -c xserver-xorg-video-all
5
$ mlocate -c -A -b xserver-xorg-video-all md5
1

Symbolic links and file existence test

Already indexed files are used in this section as an example.

~/link_test$ ls -l
total 0
lrwxrwxrwx 1 milosz milosz 5 Nov 29 22:49 badlink -> file2
-rw-r--r-- 1 milosz milosz 0 Nov 29 22:49 file1
-rw-r--r-- 1 milosz milosz 0 Nov 29 22:49 file3
lrwxrwxrwx 1 milosz milosz 5 Nov 29 22:49 goodlink -> file1

I have removed file3 file to illustrate the existence test.

~/link_test$ rm file3

By default file existence test is omitted.

$ mlocate link_test
/home/milosz/link_test
/home/milosz/link_test/badlink
/home/milosz/link_test/file1
/home/milosz/link_test/file3
/home/milosz/link_test/goodlink

Use -e and -L parameters to check for file existence and follow symbolic links.

$ mlocate -e -L link_test
/home/milosz/link_test
/home/milosz/link_test/file1
/home/milosz/link_test/goodlink
The -L parameter would be used implicitly in the above example, so you can skip it.

Use -e and -P parameters to check for file existence, but do not follow symbolic links.

$ mlocate -e -P link_test
/home/milosz/link_test
/home/milosz/link_test/badlink
/home/milosz/link_test/file1
/home/milosz/link_test/goodlink

Statistics

Use -c parameter to print the database.

$ mlocate -S
Database /var/lib/mlocate/mlocate.db:
	26,232 directories
	296,055 files
	16,729,505 bytes in file names
	7,427,440 bytes used to store database

Database update process

The configuration is stored using /etc/updatedb.conf file.

PRUNE_BIND_MOUNTS="yes"
# PRUNENAMES=".git .bzr .hg .svn"
PRUNEPATHS="/tmp /var/spool /media"
PRUNEFS="NFS nfs nfs4 rpc_pipefs afs binfmt_misc proc smbfs autofs iso9660 ncpfs coda devpts ftpfs devfs mfs shfs sysfs cifs lustre tmpfs usbfs udf fuse.glusterfs fuse.sshfs curlftpfs"

It is used to define a list of directory names, pathnames, and file system types, which should not be scanned during the update process.

Update the database using the following command.

$ sudo updatedb

This command is executed daily using cron (inspect /etc/cron.daily/mlocate shell script).

Ending notes

It is possible to deliberately use the classic insecure locate application, so verify default utility using the Debian alternatives system.

$ update-alternatives --display locate
locate - auto mode
  link currently points to /usr/bin/mlocate
/usr/bin/locate.findutils - priority 20
  slave locate.1.gz: /usr/share/man/man1/locate.findutils.1.gz
  slave updatedb: /usr/bin/updatedb.findutils
  slave updatedb.1.gz: /usr/share/man/man1/updatedb.findutils.1.gz
/usr/bin/mlocate - priority 80
  slave locate.1.gz: /usr/share/man/man1/mlocate.1.gz
  slave updatedb: /usr/bin/updatedb.mlocate
Current 'best' version is '/usr/bin/mlocate'.

Use the following commands if you need to alter the default locate utility.

$ update-alternatives --list locate
/usr/bin/locate.findutils
/usr/bin/mlocate
$ sudo update-alternatives --set locate /usr/bin/mlocate