Is there a way to use update command to locate files on OS X without having to run updatedb manually?

Solution 1:

If you want locate to update more frequently, you have to modify the /System/Library/LaunchDaemons/com.apple.locate.plist file.

Specifically, you want to find the <key>StartCalendarInterval</key> section and modify it to your specifications. By default, locate is configured to update at 3:15am every Saturday (Sunday being the first day staring with 0).

<key>StartCalendarInterval</key>
        <dict>
                <key>Hour</key>
                <integer>3</integer>
                <key>Minute</key>
                <integer>15</integer>
                <key>Weekday</key>
                <integer>6</integer>
        </dict>

This works like cron, so you can specify an asterisk if you want, for example to run it every day. Just change the 6 to and * and it will run at 3:15 every day.

An easier way to do this if you want to have it run at a set interval, for example, every 3 hours, you can use the StartInterval <integer> directive. So, for your task to run every three hours insert the following directive into the plist file:

<key StartInterval</key>
   <integer>108000</integer>

The integer is the number of seconds. So, 60 seconds in a minute, 60 minutes in an hour and so forth.

Don't forget to remove the StartCalendarInterval directive.

Last, but definitely not least...make a backup copy of your .plist file before modifying it. This way, if you hose things up, you have a good config to fall back on.

Note: In order to make these changes work under OS X El Capitan, you need to disable OS X's System Integrity Protection (SIP). You can ONLY do that by using csrutil in system Recovery Mode.

Boot Mac in System Recovery by holding Command+R.

Using Terminal, enter csrutil disable

You should see the following: Successfully disabled System Integrity Protection. Please restart machine for changes to take effect.

Reboot.

locate should now update per your schedule.

Disclaimer: This is not a recommended procedure. While this answer technically does address the question, it doesn't cover the "Why is this necessary to alter the updatedb schedule?" question.

Solution 2:

You do not have to disable SIP for this; you can instead use the /Library directory for this. I had this same problem because I don't have my MacBook Pro on at night and I’m also used to other systems where it has daily cronjob that does this. However it is possible to set this up to do either on demand or even once the computer boots up: and no you do not need to disable SIP (despite what another answer suggests). This is how I did it; if there's anything that could be improved I’m more than happy to hear of it and certainly in my tired state I could have written something wrong or even forgotten an important step or point. I will fix any that's brought to my attention.

The standard file that does this that Apple installs is at /System/Library/LaunchDaemons/com.apple.locate.plist but you can install your own at /Library/LaunchDaemons. What I did is I copied the default Apple one first to a temporary directory, made some modifications and then moved it to the second directory: then I updated the system (see below) so that it runs on start up (and I believe also when you load it right then and there). There is it seems a 'standard' of some form for the name of the file but I took the name of my system and used that as part of the name. Here I'll use my handle instead:

User file example: com.pryftan.locate.plist

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.pryftan.locate</string>
<key>RunAtLoad</key>
<true/>
<key>LaunchOnlyOnce</key>
<true/>
<key>ProgramArguments</key>
<array>
    <string>/usr/libexec/locate.updatedb</string>
</array>
<key>LowPriorityIO</key>
<true/>
<key>Nice</key>
<integer>5</integer>
<key>KeepAlive</key>
<dict>
    <key>PathState</key>
    <dict>
        <key>/var/db/locate.database</key>
        <false/>
    </dict>
</dict>
<key>AbandonProcessGroup</key>
<true/>
</dict>
</plist>  

Installing the file (where '$' is the command prompt):

$ sudo cp com.pryftan.locate.plist /Library/LaunchDaemons
$ sudo launchctl load -w /Library/LaunchDaemons/com.pryftan.locate.plist

Additional notes

Observe that the name of the file (minus the .plist part) is in the file itself; whatever you name the file should also be updated in the file as well.

After installing the file and loading it the system should start immediately the /usr/libexec/locate.updatedb command. It makes use of /tmp for some temporary files and then after it's done of course it removes those files. You'll then see if you look at the database file that it's been updated (or modified).

Note the -w option to the command above is not strictly necessary: that's only if there is a 'Disabled' key in the file but since I first saw the invocation of the command with that option I kept it in there even after removing that key.

If you want to update the database manually you can run the command directly (or - so it appears from a test a moment ago - you can reload by using the same launchctl load command as above):

$ sudo /usr/libexec/locate.updatedb

Oh and in a comment to another answer I noted how it does in fact show user directories. Actually thinking on that it's to do with permissions most likely; certainly that's the case in Linux. This makes sense of course; it's not a limitation of the command but a security and privacy mechanism that's part of the OS itself. That is to say that although the database has all the files the user cannot see files that it does not have permission (directories) to see.

One more thing: I did have an initial issue with formatting with the file above so if there is an error please let me know and I'll see about fixing it (when I check messages - I do have very much going on right now). If there are any errors the same goes. I do know in any case that what I have works so as long as everything is done as explained - and as long as I explained (and pasted) well it should be what you need: if you do want to have it updated every time on boot up. If not you can do as another answer says only that you can put the file in the directory I noted rather than modify the system file itself.