iEFdev

Code, Computers & Random Junk

How to Enable and Use “locate”

Here is how to enable and setup locate. It will focus on OS X, but it’s pretty much simular on any system (that can use locate).

“Spotlight” is really great, and you’ll find stuff on your computer as they are made. Though, it doesn’t search too deep. To find files/folders deep within your system you will have to open a Finder window, and add “system files” as criteria to your search. Anyway - it’s great and has all those preview functions etc… But, this isn’t about Spotlight, it’s about locate.

Create the database

If you never have used locate before, you’ll first need to create the database. Do that by running:

sudo /usr/libexec/locate.updatedb

(perhaps the location of that file is different on different systems)

On OS X you can also start it by loading the LaunchAgent.

sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

It will just take a few minutes to be done. Then you can start using it like:

locate myfile.jpg

More on usage later on.

Updating the database

To update the database, you can either do it manually by running the same program that created the database, or add it to your crontab. When using the LaunchDaemon on OS X - the database will update once a week.

Manually

sudo /usr/libexec/locate.updatedb

Or add an alias to your alias file.

# manually update locate
alias locateupd='sudo /usr/libexec/locate.updatedb'

Crontab (@daily)

3 15 * * * /usr/libexec/locate.updatedb

For the OS X LaunchDaemon… Open the file com.apple.locate.plist with TextWrangler, BBEdit or another good text editor. At the bottom of the file you’ll find:

1
2
3
4
5
6
7
8
9
<key>StartCalendarInterval</key>
<dict>
  <key>Hour</key>
  <integer>3</integer>
  <key>Minute</key>
  <integer>15</integer>
  <key>Weekday</key>
  <integer>6</integer>
</dict>

That is once a week, so we will remove the “Weekday” so it updates every day instead of once a week. A lot of stuff happens in a week. smirk

1
2
3
4
5
6
7
<key>StartCalendarInterval</key>
<dict>
  <key>Hour</key>
  <integer>3</integer>
  <key>Minute</key>
  <integer>15</integer>
</dict>

Of course, you could also change that into:

1
2
<key>StartInterval</key>
<integer>43200</integer>

That will update the database every 6 hour (3600(sec) = 1h).

To reload it again:

sudo launchctl unload -w /System/Library/LaunchDaemons/com.apple.locate.plist
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist

Tweaks

Depending on how your computer is setup, the number of disks you have, or more exactly … what’s on them, you might want to add a few tweaks.

On my computer I have a couple of xtra disks. One is one of the clones of the system disk. Another one keeps an older system I use when cloning (doing so, I can perform a block-level clone). That will produce a lot of duplicates when using locate. To avoid that… either edit the locate.updatedb file, or add your tweaks to /etc/locate.rc

In that file everything is commented by default, so uncomment the PRUNEPATH, then copy the paths from locate.updatedb and replace the ones + add your own. In my case it looks like: (/etc/locate.rc)

# directories unwanted in output
PRUNEPATHS="/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb /Volumes/*Backup /Volumes/FooName"

If your system supports other file systems you can also uncomment FILESYSTEMS to include those. Example:

FILESYSTEMS="hfs ufs ext2 ext3 ext4"

Since I save most of my files, pictures etc on another disk, I also have a function I use to narrow the results down.

# locate in Foo
function Locate { locate $* | egrep "^/Volumes/Foo"; }

That will only look in the disk “Foo”

Creating a user based version

If you don’t care too much about system files and more care about integrity. You could easliy set up a local version instead. Meaning, your database and your files can’t be found by other users on the computer when using locate.

What we’re going to need is to copy the program into our home directory, and edit the different paths to match. For OS X we’ll also copy the (original) LaunchDaemon in to ~/Library/LaunchAgents, which is the user defined location for LaunchDaemons.

The location in your home directory will be ~/Library/Locate, but could really be anywhere - just use the correct paths in your edits.

So, first we create the folder and copy the stuff into it. We’re also going to use the name llocate.

mkdir -pv ~/Library/Locate && cd ~/Library/Locate
cp /usr/libexec/locate.updatedb llocate.updatedb

# make sure it has permissions
chmod 755 llocate.dbupdate

cd ~/Library/LaunchAgents
cp /System/Library/LaunchDaemons/com.apple.locate.plist com.apple.llocate.plist

For the com.apple.llocate.plist we need to make a few changes. Label to match the new name of the file. PathState and ProgramArguments can’t use ~ or $HOME - it has to be the full path. And the StartCalendarInterval will be replaced by StartInterval … updating every hour.

The final result looks like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>AbandonProcessGroup</key>
  <true/>
  <key>Disabled</key>
  <true/>
  <key>KeepAlive</key>
  <dict>
      <key>PathState</key>
      <dict>
          <key>/Users/YourUserName/Library/Locate/llocate.database</key>
          <false/>
      </dict>
  </dict>
  <key>Label</key>
  <string>com.apple.llocate</string>
  <key>LowPriorityIO</key>
  <true/>
  <key>Nice</key>
  <integer>5</integer>
  <key>ProgramArguments</key>
  <array>
      <string>/Users/YourUserName/Library/Locate/llocate.updatedb</string>
  </array>
  <key>StartInterval</key>
  <integer>3600</integer>
</dict>
</plist>

Now open the program file: llocate.updatedb. The lines to be edited are:

: ${FCODES:=/var/db/locate.database}    # the database
: ${SEARCHPATHS:="/"}                   # directories to be put in the database
: ${PRUNEPATHS:="/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb"} # unwanted directories

Replace that with:

: ${FCODES:=$HOME/Library/Locate/llocate.database}  # the database
: ${SEARCHPATHS:="$HOME"}                           # directories to be put in the database
: ${PRUNEPATHS:="$HOME/tmp $HOME/Library/Locate"}   # unwanted directories

Save the file and start the service:

launchctl load -w ~/Library/LaunchAgents/com.apple.llocate.plist

It’ll go a lot faster since it’s only the user home directory.

To use it, add an alias to your alias file.

# locate home dir (llocate)
alias llocate='locate -d $HOME/Library/Locate/llocate.database'

A note on this one… It seems like locate doesn’t follow symlinks - like in my case where I have symlinks from ~/Pictures -> /Volumes/Foo/Pictures (example). So, it’s not so useful if you’ve split up your home directory like that.

To update the database if not using the LaunchAgent, it’s like before, but you use this file/location instead.

Manually

~/Library/Locate/llocate.updatedb

Or add an alias to your alias file.

# manually update llocate
alias llocateupd='~/Library/Locate/llocate.updatedb'

Crontab (@hourly)

0 * * * * ~/Library/Locate/llocate.updatedb

Usage

Using locate is quite simple, and is a h*ll lot faster than Spotlight. smirk

# a file
locate filename.ext

# all jpg's
locate *.jpg

If you’re clueless about the file name, perhaps it’s using a “camelCaseName”. Use -i for that.

# another file
locate -i myfile.ext

# will match myfile.ext, Myfile.ext, myFile.ext, MyFile.ext etc.

Read more in the manual(s).


Locate is really great… Lightweight, super fast and easy to use/manage. But, it doesn’t seem to follow symlinks, and the list of results can be really big since it returning really everything.

Comments