Решение вашей проблемы очень простое (и его можно найти в конце этого ответа). Но если вы хотите лучше понять, почему происходит ошибка и почему работает предложенное решение, вы можете прочитать весь ответ.
Что именно делает locate.updatedb?
Это текущее поведение locate.updatedb
:
- Если вы запускаете сценарий от имени пользователя
root
, он снова вызывает себя с пользователем nobody
и затем дочерние элементы возвращаются, он обновляет окончательную базу данных локали с базой данных, сохраненной процессом детей (nobody
) во временном расположении, и затем завершает работу ;
Код (/usr/libexec/locate.updatedb
, строка 31, с добавленными мной дополнительными комментариями):
if [ "$(id -u)" = "0" ]; then ## IF ROOT USER
rc=0
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
fi
rm $FCODES
exit $rc ## EXIT
fi
- При работе с другим пользователем (то есть с пользователем
nobody
) скрипт индексирует вашу систему (игнорируя пути, на которые у него нет разрешения), а затем сохраняет результат во временный файл (фактически, ранее временный файл, созданный его отец);
- Итак, часть логики выполняется как корень, а другая часть как никто ;
- Если скрипт вызывается без
sudo
, он не будет работать (только у пользователя root
есть разрешение в каталоге /var/db
). То есть, вы действительно должны изначально запустить скрипт от имени root
;
- В результате
locate.updatedb
не может индексировать файлы внутри вашего дома (у пользователя nobody
нет доступа к нему);
- Я думаю, что
locate.updatedb
индексирует этот путь, потому что пользователю будет невозможно обнаружить имена файлов, принадлежащих другому пользователю (в другом домашнем каталоге);
- Если вы хотите найти файлы внутри своего дома, вы можете использовать
mdfind
, как предложено @ ted-naleid.
Некоторый код (/usr/libexec/locate.updatedb
, строка 93, с дополнительными комментариями):
if $find -s $SEARCHPATHS $excludes -or -print 2>/dev/null | ## SEARCH
$mklocatedb -presort > $tmp ## CREATE LOCALEDB
then
case X"`$find $tmp -size -257c -print`" in
X) cat $tmp > $FCODES;; ## SAVE LOCALEDB IN THE TEMP FILE
[...]
Почему вы получаете ошибки "Отказано в доступе"?
Было сказано, что locale.updatedb
запускает новый экземпляр себя как пользователь nobody
. Однако вы не можете запустить скрипт внутри рабочего каталога, на который у скрипта нет разрешения .
Возможно, вы получаете ошибки " Отказано в доступе ", потому что вы запускаете locale.updatedb
в вашем доме.
Я создаю простой скрипт, чтобы показать этот факт:
#!/bin/bash
if [ $(id -un) != "nobody" ]; then
sudo -u nobody "$0"
exit 0
fi
find / -mindepth 1 -maxdepth 1 | wc -l
Если вы поместите этот скрипт в /tmp/test.sh
и установите для него разрешение на выполнение (chmod +x /tmp/test.sh
), в зависимости от вашего рабочего каталога, он может показывать или не отображать ошибки:
$ cd /tmp
$ ./test.sh
29
$ 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
0
Как обновить вашу базу данных locate?
Теперь все просто! Измените ваш рабочий каталог на место, где nobody
имеет разрешения перед выполнением locale.updatedb
:
cd /
sudo /usr/libexec/locate.updatedb