无法手动更新数据库以进行定位?

mem*_*nuk 7 mac locate macos

我一直在尝试更新 locate 在我的 Macbook(10.6.3 Snow Leopard)上使用的数据库,但即使按照此线程中显示的命令也没有让我到任何地方。我只是从中得到一个错误 - 如果我尝试通过 sudo 使用它,我会收到一些关于此类目录的权限被拒绝的问题。我尝试以 root 身份运行它(sudo su,然后是命令),但也没有用。退出我的常规终端提示,现在我得到

macbook:~ monte$ sudo /usr/libexec/locate.updatedb
find: .: 权限被拒绝
macbook:~ monte$

我彻底糊涂了,有点害怕我可能在这个过程中弄脏了一些东西。任何帮助或建议将不胜感激!

蒙特

Ted*_*eid 7

您可能想要尝试修复文件权限(在“磁盘工具”应用程序中)。听起来这可能是一个问题。

此外,与 locate 没有直接关系,但我发现在 Mac 上,mdfind 实际上比 locate 做得更好。这是突出显示的命令行界面,如果您想模拟定位,它可以让您仅按文件名查找:

mdfind -name <filename>
Run Code Online (Sandbox Code Playgroud)

只需使用“mdfind”即可找到两个文件名并查看文件内部(将 grep/find 放在一起)。

无需手动更新数据库,因为 OSX 会为您维护聚光灯信息。


Rar*_*tas 7

您的问题的解决方案非常简单。但是,如果您想更好地了解错误发生的原因以及建议的解决方案为何有效,您可以阅读整个答案。

否则,如果您只想得到答案,请直接转到“如何更新您的定位数据库?” 会议。

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
Run Code Online (Sandbox Code Playgroud)
  • 当与另一个用户(即用户nobody)一起运行时,脚本会索引您的系统(忽略它没有权限的路径),然后将结果保存在一个临时文件中(实际上,之前由其父亲创建的临时文件) )。

一些考虑:

  • 部分逻辑以root身份执行,另一部分以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
[...]
Run Code Online (Sandbox Code Playgroud)

为什么会出现“权限被拒绝”错误?

正如我所说,locale.updatedbnobody用户身份启动一个新的实例。但是,您不能在脚本没有权限的工作目录中启动脚本

您可能会收到“权限被拒绝”错误,因为locale.updatedb您在家中跑步。

我正在创建一个简单的脚本来显示这个事实:

#!/bin/bash

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

find / -mindepth 1 -maxdepth 1 | wc -l
Run Code Online (Sandbox Code Playgroud)

如果您将此脚本放入其中/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
Run Code Online (Sandbox Code Playgroud)

如何更新您的定位数据库?

现在,这很简单!仅nobody在执行之前将您的工作目录更改为具有权限的位置locale.updatedb

cd /
sudo /usr/libexec/locate.updatedb
Run Code Online (Sandbox Code Playgroud)