I am considering using an alias for locate, as I find really inconvenient to have to run updatedb so often on mac.
Do you have any ideas or workarounds for this?
Ask Different is a question and answer site for power users of Apple hardware and software. It only takes a minute to sign up.Sign up to join this community
If you want locate to update more frequently, you have to modify the
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
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
You should see the following:
Successfully disabled System Integrity Protection. Please restart machine for changes to take effect.
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.
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:
<?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>
$ sudo cp com.pryftan.locate.plist /Library/LaunchDaemons $ sudo launchctl load -w /Library/LaunchDaemons/com.pryftan.locate.plist
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).
-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.
Locate always consults a database that is either out of date, periodically updated or not created in the first place by default.
You can load the weekly task to regenerate this with one command:
sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist
On OS X, you would be better off using
mdfind which uses the spotlight database and is designed to update continually and provide real time updates to the index.
mdfind queries show rapid results when any other process creates a file that matches your search criteria - the result will arrive nearly instantly.
Changing your alias to use
mdfind instead of
locate allows you to work around the design limitations of
locate and the
find command it uses to crawl the filesystem.
locate's database is by default only updated weekly. Changing its schedule needs disabling SIP, as already explained, which means disabling security mechanisms put there for your protection. Not recommended.
locate seems to only find "public" files - so, not the files under your home directory.
mdfind will rather only find things that a Spotlight search finds. For example, it seems to miss files inside of file bundles. And it's somewhere between inconvenient, imprecise and useless if you only want to find based on filenames.
The last, but classic, option is to use the
find command in terminal. It has lots of options, so better check
man find. But the basic, locate-like usage is simple:
find <root directory for search> -iname <filename_with_wildcards>. It will probably be slow (depending on how big is the part of the filesystem tree where you are searching), but it shows you the current state of the filesystem, as seen by the current user. So, run it with sudo and you'll search all the files in the system.
And if you want to find without dropping to the Terminal level, you can try the freeware EasyFind by Devon Techonologies. Works well.