3

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?

  • 1
    Does it have to be locate? Have You seen mdfind ? – Mateusz Szlosek Feb 19 '16 at 12:37
  • Can you expand more? Using Yosemite and Finder, files and locations are updated almost instantaneously so I have no frame of reference to your question. – Allan Feb 19 '16 at 12:59
  • 1
    @Allan from man locate -> The database is recomputed periodically (usually weekly or daily), and contains the path- names of all files which are publicly accessible. – Mateusz Szlosek Feb 19 '16 at 13:26
5

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.

  • 3
    What about SIP in System/Library/LaunchDaemons ? – Mateusz Szlosek Feb 19 '16 at 14:08
  • 1
    While the OP didn't state what version of OS X he's running nonetheless Mateusz Szlosek brought up a valid point. So you might want to add info about SIP and disabling/enabling it. – user3439894 Feb 19 '16 at 15:08
  • 1
    That's true...I forgot about System Integrity Protection. I will update my answer. – Allan Feb 19 '16 at 15:49
  • You actually do not have to update it - at least now, maybe then when you first answered - in the system directory. You can do it under /Library instead. See my answer for the details there. This means you do not have to disable SIP and that's a good thing. – Pryftan Jul 1 at 12:16
  • Is there a way to run this so it is actually synced. Meaning if I delete then things get removed. Also if add, things get added to the index? – momomo Jul 30 at 19:37
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.

  • Is there a way to run this so it is actually synced. Meaning if I delete then things get removed. Also if add, things get added to the index? – momomo Jul 30 at 19:35
  • @momo Sorry about the delay. I have a lot going on. Are you trying to say that if after this is run you delete a file or make a new file or directory it will then be accounted for in the database? No it's not possible directly. It would be constantly polling the file system(s) for file changes and updating the database very often. It's not what you would want. That being said if you do want to update it manually you can do what I noted in the answer: sudo /usr/libexec/locate.updatedb – Pryftan Aug 2 at 15:42
  • @momo I have had the thought of giving an alternative service that updates every X hours or however long. That would probably be the closest you could have. For instance you could have it update every hour. Is that sufficient? – Pryftan Aug 2 at 15:43
  • @Pryflan I found out mdfind does this ... i think it uses spotlight index which might be equal to locate – momomo Aug 2 at 18:54
  • @mono It's similar anyway. It however uses more resources (obviously). It's a different thing actually (at least Spotlight is - maybe mdfind too but I do not know for sure) because locate is simply a database that stores locations of files when the database was last generated. But if mdfind works better for you (and yes afaik it uses Spotlight) then that's great. Thanks for the comment(s). Cheers. – Pryftan Aug 8 at 18:04
1

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.

These live 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.

  • 1
    mdfind does still miss some hidden and system files in my experience, even when you give it the tortuous arguments to include them in the results. – calum_b Feb 19 '16 at 17:42
  • @calum_b That's most likely a permissions issue rather than the command itself. – Pryftan Jul 1 at 12:18
  • Not really; by default the locate db is not created at all on macOS, and when you do create it, it never updates again unless you issue a launchctl command. And then it only updates it once a week by default. apple.stackexchange.com/a/14842/2841 – calum_b Jul 4 at 14:53
  • @calum_b is right, the syntax to search non standard locations like /usr is painful to remember so I have to look it up regularly – bmike Jul 4 at 15:06
  • 1
    I should also point out that you can - if you're going to use the same parameters i.e. not modifying the file or schedule - just as well run the command directly. Shorter in any case than the command given. Not saying it doesn't work though just it's more to type. Oh and it's not a design limitation of locate or the find commands. An out of date database is because of the scheduling and not the command itself. And as for find it's immensely powerful if you know how to use it. You don't want it to be able to see all users' files either esp since you can run commands on them... – Pryftan Jul 4 at 23:38
0

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. Also, 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.

  • I realise your post is some years old but at least in Mojave locate does in fact show files in home directories. I’m pretty sure it also did it in Safari; it's a command I use in different Unices and when I got my MacBook Pro in 2018 I am certain I used it and saw files in home directories (which I keep wanting to type /home and having to pause!) and I got it in March of last year so long before the update to Mojave. – Pryftan Jan 22 at 18:53
  • Is there a way to run this so it is actually synced. Meaning if I delete then things get removed. Also if add, things get added to the index? I don't care about SIP. – momomo Jul 30 at 19:35

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .