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;
/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
chown nobody $FCODES # TEMP FILE OWNED BY THE NOBODY USER
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
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
- 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
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"
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"
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
$ cd ~
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