Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

I've been trying to update the databases used by locate on my Macbook (10.6.3 Snow Leopard) but even following the commands shown in this thread hasn't gotten me anywhere. I just get an error from it - if I try to use it via sudo, I get some racket about permission denied for such-n-such directory. I tried running it as root (sudo su, then the command) and that didn't work either. Quit back to my regular terminal prompt, and now I just get

macbook:~ monte$ sudo /usr/libexec/locate.updatedb
find: .: Permission denied
macbook:~ monte$

I'm thoroughly confused, and half afraid that I may have hosed something in the process. Any help or suggestions would be greatly appreciated!


share|improve this question

4 Answers 4

You might want to try to repair file permissions (in the Disk Utility application). Sounds like it might be an issue with that.

Also, not directly related to locate, but I've found that on the mac that mdfind actually does what I want quite a bit better than locate does. It's the command line interface to spotlight, and it lets you find just by file name if you want to mimic locate:

mdfind -name <filename>

Just using "mdfind " will find both file names and look inside files (sort of grep/find put together).

No need to manually update the database for it as OSX maintains the spotlight information for you.

share|improve this answer
Apparently the disk did(does) have some issues... I needed to boot from a backup disk and repair some problems (some file links), after which I booted off the main internal drive and repaired the permissions - and there was a whole slew of corrections. The bizarre part is if I re-run the 'repair permissions' option after clearing the display... I get most of the same errors again (says that 'SUID file "System/Library/..." has been modified and will not be repaired. And I still get the same message when I tried to run locate.updatedb via sudo. –  memilanuk Jul 9 '10 at 5:20
launchctl load -wF /System/Library/LaunchDaemons/com.apple.locate.plist

If it doesn't help, try:

launchctl stop com.apple.locate

launchctl start com.apple.locate
share|improve this answer
Take a look inside the plist -- the LaunchDaemon does nothing but executing /usr/libexec/locate.updatedb itself. The user has a permissions issue running it as root. Why'd it work when running via launch? –  Daniel Beck Jan 25 '11 at 14:28

(this is a bit old, but since I was digging on a similar problem with 10.6 today...)

macbook:~ monte$ sudo /usr/libexec/locate.updatedb
find: .: Permission denied
macbook:~ monte$

this isn't a problem, exactly - it's a side effect of locate.updatedb su'ing to nobody, but your home directory isn't readable by the "nobody" user.

You'll probably find that system files are still findable with locate, but nothing inside your home directory is. You'll need to make your homedir world readable/executable. For example:

chmod a+rx $HOME

You may need to review the contents of your homedir, too - but it's likely you dont want to do a recursive chmod across the entire tree. (~/.ssh, for example, has specific requirements). If you have a custom umask set, you'll want to review that as well.

As a hackaround alternative you could edit the /usr/libexec/locate.updatedb script to not switch to the nobody user:

if [ "$(id -u)" = "0" ]; then
    export FCODES=`mktemp -t updatedb`
    chown nobody $FCODES
    tmpdb=`su -fm nobody -c "$0"` || rc=1
    if [ $rc = 0 ]; then
            install -m 0444 -o nobody -g wheel $FCODES /var/db/locate.database
    rm $FCODES
    exit $rc

Remove or comment out that block - or just tweak the test to something else -

if [ "$(id -u)" = "-99" ]; then

This should work regardless of how the update is called - by launchd, or manually. But could revert if you update the OS. (though lets face it, in 2014 if you're still running 10.6, you're probably not going to update now ;)

share|improve this answer

The solution for your problem is very simple (and it can be found at the end of this answer). But if you want to know better why the error are occurring and why the proposed solution works, you can read the entire solution.

What exactly does locate.updatedb?

This is the currently behavior:

  • If you are running locale as root, calls the same script again with the nobody user, updates the final locale database with the database saved by its children in a temporary location, and then exits;

Code (/usr/libexec/locate.updatedb, line 31, with additional comments):

if [ "$(id -u)" = "0" ]; then  ## ROOT USER
    export FCODES=`mktemp -t updatedb`  ## CREATE A TEMP FILE
    tmpdb=`su -fm nobody -c "$0"` || rc=1  ## CALL ITSELF AS USER NOBODY
    if [ $rc = 0 ]; then
        install -m 0444 -o nobody -g wheel $FCODES \
            /var/db/locate.database  ## INSTALL THE LOCATE DATABASE SAVED \
                                     ## BY THE CHILDREN IN THE TEMP FILE
    rm $FCODES
    exit $rc  ## EXIT
  • When running with another user (like the nobody user), the script indexes your system (ignoring the paths which it doesn't have permission) and then saves the result in a temporary file (previously created by the father);
    • So, part of the logic is executed as the root user, and other part as the nobody user;
    • If the script was called without sudo, the temporary directory would be set to /var/db/locate.database. However, your user has no permission in /var/db, so it wouldn't work (only root actually has it). It is, you really must initially run the script as root;
    • As a result, locate.updatedb cannot index files inside your home (the nobody user doesn't permission to access it);
    • I think Yosemite's locate.updatedb indexes this way because it makes impossible an user to discover names of files that belongs to another user (in another home directory);
    • To locate things including your home, you can use mdfind :).

Some code (/usr/libexec/locate.updatedb, line 93, with additional comments):

if $find -s $SEARCHPATHS $excludes -or -print 2>/dev/null |  ## SEARCH
        $mklocatedb -presort > $tmp  ## CREATE LOCALEDB
    case X"`$find $tmp -size -257c -print`" in
        X) cat $tmp > $FCODES;;  ## SAVE LOCALEDB IN THE TEMP FILE
        *) echo "updatedb: locate database $tmp is empty"
           exit 1

Why are you getting "Permission Denied" errors?

The new behavior of locale.updatedb launchs a new instance of the script as the nobody user. However, you can't start a script using a workdir in which the script has no permission.

So, probably, you are getting "Permission denied" errors because you're running locale.updatedb inside your home.

I'm creating a simple script to show the previous fact:


if [ $(id -un) != "nobody" ]; then
    sudo -u nobody "$0"
    exit 0

find / -mindepth 1 -maxdepth 1 | wc -l

If you put this script inside /tmp/test.sh and set execution permission to it (chmod +x /tmp/test.sh), depending of your workdir, it can show or not errors:

$ cd /tmp
$ ./test.sh 
$ cd ~
$ /tmp/test.sh
shell-init: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
job-working-directory: error retrieving current directory: getcwd: cannot access parent directories: Permission denied
find: .: Permission denied

How to update your locate db?

Now, its simple! Only change your workdir to a place where nobody has permission before executing locale.updatedb:

cd /
sudo /usr/libexec/locate.updatedb
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.