A solução para o seu problema é muito simples (e pode ser encontrada no final desta resposta). Mas se você quiser saber melhor por que o erro está ocorrendo e por que a solução proposta funciona, você pode ler a resposta inteira.
O que exatamente localiza.updatedb?
Este é o comportamento atual de locate.updatedb
:
- Se você estiver executando o script como
root
, ele se chamará novamente com o usuário nobody
e, em seguida, os filhos retornarão, ele atualizará o banco de dados de locale final com o banco de dados salvo pelo processo filho ( nobody
user ) em um local temporário e, em seguida, sai;
Código ( /usr/libexec/locate.updatedb
, linha 31, com comentários adicionais adicionados por mim):
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
- Ao executar com outro usuário (ou seja, o usuário
nobody
), o script indexa seu sistema (ignorando os caminhos que ele não tem permissão) e, em seguida, salva o resultado em um arquivo temporário (na verdade, arquivo temporário criado por seu pai);
- Assim, parte da lógica é executada como raiz e outra parte como ninguém ;
- Se o script for chamado sem
sudo
, não funcionará (somente root
tem permissão no diretório /var/db
). É, você deve inicialmente executar o script como root
;
- Como resultado,
locate.updatedb
não pode indexar arquivos dentro de sua casa (o usuário nobody
não tem permissão para acessá-lo);
- Acho que
locate.updatedb
indexa dessa maneira porque será impossível para um usuário descobrir o nome dos arquivos que pertencem a outro usuário (em outro diretório inicial);
- Se você quiser localizar arquivos em sua casa, use
mdfind
, conforme proposto por @ ted-naleid.
Algum código ( /usr/libexec/locate.updatedb
, linha 93, com comentários adicionais):
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
[...]
Por que você está recebendo erros de "Permissão negada"?
Foi dito que locale.updatedb
lança uma nova instância de si mesmo como o usuário nobody
. No entanto, você não pode iniciar um script dentro de um workdir no qual o script não tenha permissão .
Provavelmente, você está recebendo erros de "Permissão negada" porque está executando locale.updatedb
em sua casa.
Estou criando um script simples para mostrar esse fato:
#!/bin/bash
if [ $(id -un) != "nobody" ]; then
sudo -u nobody "$0"
exit 0
fi
find / -mindepth 1 -maxdepth 1 | wc -l
Se você colocar esse script dentro de /tmp/test.sh
e definir a permissão de execução para ele ( chmod +x /tmp/test.sh
), dependendo do seu workdir, ele poderá mostrar ou não erros:
$ 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
Como atualizar seu db de localização?
Agora é simples! Altere apenas o seu workdir para um local em que nobody
tenha permissão antes de executar locale.updatedb
:
cd /
sudo /usr/libexec/locate.updatedb