GNU-Version von locate – gupdatedb schlägt mit „gfind: failed to read file names from file system“ fehl

Ich versuche, die GNU-Version des Befehls zu testen locate. Zuerst muss ich die Datenbank wie folgt erstellen:

sudo gupdatedb --prunepaths=/Volumes --output=$HOME/locatedb_gupdatedb

Leider erhalte ich 1 Minute nach dem Start des Befehls immer noch die folgende Fehlermeldung:

gfind: failed to read file names from file system at or below '/': No such file or directory

Ich verstehe nicht, woher dieser Fehler kommen könnte?

UPDATE 1: Ich habe es gfinddurch findein Komma und den korrekten Pfad ersetzt, finddessen /usr/bin/. Leider bekomme ich peinliche Fehlermeldungen wie diese, wenn ich den gupdatedbBefehl wie folgt starte:

sudo gupdatedb --prunepaths='/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb /Volumes /System' --output=$HOME/locatedb_gupdatedb

Hier die Fehlermeldungen:

find: /System/Volumes/Data/.Spotlight-V100: No such file or directory
find: /System/Volumes/Data/.PKInstallSandboxManager: No such file or directory
find: /System/Volumes/Data/.PKInstallSandboxManager-SystemSoftware: No such file or directory
find: /System/Volumes/Data/.cleverfiles: No such file or directory
find: /System/Volumes/Data/mnt: No such file or directory
find: /System/Volumes/Data/.DocumentRevisions-V100: No such file or directory
etc ...

/usr/local/Cellar/findutils/4.7.0/libexec/bin/gupdatedbIch habe versucht , die Option in die Datei zu ändern :

: ${FINDOPTIONS="2 > /dev/null"}

Aber das Problem ist, dass diese Option vor dem Befehl gesetzt wird find, nicht am Ende, also ist sie im Folgenden der Datei nicht korrekt.

findAngesichts der Tatsache , dass das Skript viele Befehle enthält , kann ich die 2 > /dev/nullTerminaloption nicht jedes Mal manuell hinzufügen.

Jeder konnte sehen, wie man all diese Fehlermeldungen vom findBefehl unterdrückt, wenn ich einen gupdatedbBefehl starte?

UPDATE 2: Ich habe es endlich geschafft, eine Datenbank mit gupdatedb (GNU-Version des MacOS- updatedbBefehls) zu erstellen, indem ich Folgendes mache:

sudo gupdatedb --prunepaths='/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb /System /Volumes' --output=$HOME/locatedb_gupdatedb

Das Problem ist jetzt, wenn ich eine Suche nach einer Teilzeichenfolge einer Datei oder eines Verzeichnisses durchführe, scheinen die Informationen in den Ergebnissen dupliziert zu werden ( sub_stringist einfach der Teil eines Datei- oder Verzeichnisnamens):

Wenn ich z.B. folgendes mache:glocate -d ~/locatedb_gupdatedb sub_string

Dann habe ich doppelte Ergebnisse wie:

/System/Volumes/Data/Users/fab/sub_string.dat
/Users/fab/sub_string.dat

Ich weiß nicht, wie ich ' /System/Volumes/Data/' aus diesen Ergebnissen ausschließen soll: Ich habe jedoch in --prunepathsder Option das Verzeichnis genau angegeben System, warum wird es in der von erstellten Datenbank nicht berücksichtigt gupdatedb?

Oder vielleicht sollte ich eine durchführen:

sudo gupdatedb --prunepaths='/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb /System/Volumes/Data /Volumes' --output=$HOME/locatedb_gupdatedb

??

Jede Hilfe ist willkommen, um dieses Verzeichnis auszuschließen

/System/Volumes/Data

aus der Indizierungsdatenbank.

UPDATE 3: Hier ist ein Beispiel für die schnelle Generierung einer Datenbank mit updatedb on Debian 10 Buster. Zwischen den Zeitstempeln der beiden Befehle wurden einige Änderungen der normalen Verwendungupdatedb vorgenommen .

Geben Sie hier die Bildbeschreibung ein

Daher schließe ich, dass es wirklich einen Unterschied zwischen der GNU/MacOS- und der GNU/Linux-Implementierung gibt.

Jede Erklärung ist willkommen.

Ich bin mir nicht sicher, ob wir der richtige Ort sind, um nach Linux zu fragen, es macht Ihre Frage auch ziemlich weit gefasst.

Antworten (2)

Das Problem hier ist, dass Sie GNUs updatedbmit dem macOS ausführen find. gupdatedbist ein Shell-Skript, das erwartet, eine GNU-kompatible find. Insbesondere konvertiert es --prunepathsin einen GNU-kompatiblen einfachen regulären Ausdruck.

--prunepaths='/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb /Volumes /System'

konvertiert zu

PRUNEREGEX="\(^/private/tmp$\)\|\(^/private/var/folders$\)\|\(^/private/var/tmp$\)\|\(^*/Backups.backupdb$\)\|\(^/System$\)\|\(^/Volumes$\)"

GNU BRE (einfache reguläre Ausdrücke) behandelt \|als "alternativen" Operator:

'foo\|bar' stimmt entweder mit 'foo' oder 'bar' überein

Dies ist eine GNU-Erweiterung der BRE-Syntax, und der macOS- findOperator akzeptiert sie nicht. Die ganze Pflaumenkette stimmt also mit nichts überein.

Das macOS (und POSIX) BRE hat keinen alternativen Operator, daher ist es keine super einfache Lösung. Das macOS-Skript updatedb wandelt die Alternative in explizite -orOperatoren im findBefehl um. Dazu können Sie das GNU-Skript modifizieren. Oder mach dich gfindan die Arbeit.

Übrigens baut GNUs updatedb-Skript bei jedem Lauf eine komplett neue Datenbank auf, genau wie die von macOS.

Ihre Debian-Installation verwendet mlocate , eine völlig andere Implementierung als GNU locate, nicht so weit portiert und AFAIK nicht auf macOS verfügbar. Und obwohl mlocatees auf Ihrer Debian-Installation schnell läuft, bedeutet das nicht, dass es viel schneller läuft als GNU locate. Beide laufen unter einem zweiten Aufbau der gesamten Datenbank auf meiner Debian-Installation von Grund auf neu, wenn sich alle Festplatten-Metadaten im RAM befinden (was normalerweise der Fall ist).

Apple bietet mdfind, das die von erstellte inkrementelle Datenbank verwendet mds, die größtenteils durch Dateisystemereignisse ausgelöst wird. Dies macht es (theoretisch) viel effizienter als sogar mlocate, das immer noch die gesamte Verzeichnisstruktur durchlaufen muss, um nach geänderten Verzeichnissen zu suchen. Das Problem besteht darin, dass sich bei inkrementellen Builds Fehler ansammeln. Aus diesem Grund locateist , jedes Mal komplett neu aufgebaut, immer noch da und wird von vielen bevorzugt.

"Übrigens erstellt das Skript updatedb von GNU bei jedem Lauf eine komplett neue Datenbank, genau wie die von macOS." : Das ist bei Linux nicht der Fall, oder ?
@ youpilat13 Ich schaue mir den Code von GNU findutils 4.7.0 an . Es ist nicht spezifisch für macOS, also gehe ich davon aus, dass es unter Linux dasselbe ist. Wenn Sie sich den Code im Allgemeinen ansehen, updatedbführen Sie einfach einen findBefehl aus, um alle Dateien zu finden, und verarbeiten dann die Ausgabe in eine Datenbankdatei. Da findohnehin der gesamte Verzeichnisbaum durchsucht werden muss, um neue Dateien zu finden, bringt ein inkrementelles Update keinen Performance-Vorteil (zumindest keinen der Mühe wert).
@OlfPro Es ist seltsam, auf meinem Debian habe ich dieses Verhalten nicht, updatedb aktualisiert nur das, was zwischen der letzten Nutzung geändert wurde, normalerweise ein paar Stunden oder Minuten. Ich schließe daraus, dass die Implementierung nicht genau gleich ist.
Kennen Sie ein Tool, das nicht jedesmal die ganze Festplatte aufbaut? mdfindist ziemlich gut, aber instabil (manchmal erscheinen Ergebnisse und manchmal nicht).
@youpilat13 Lassen Sie mich wissen, welche Version von updatedb Sie auf Ihrem Debian-System ausführen. Wenn ich apt install locateDebian Buster verwende, erhalte ich die von GNU findutils 4.6.0, die eine neue erstellt $LOCATE_DB.nund bei Erfolg die alte Datenbank durch die neue ersetzt. AFAIK, mdsführt inkrementelle Updates für mdfind. Wenn mdfindetwas fehlt, das absichtlich nicht ausgeschlossen wurde (z. B. durch Datenschutzeinstellungen oder das Ausschalten der Indizierung eines Laufwerks), empfehle ich die Verwendung locate:-) Es versucht nicht, inkrementelle Updates durchzuführen, ist also viel zuverlässiger, wenn auch etwas veraltet.
@OdPro Ich habe ein Beispiel in UPDATE3 eingefügt , in dem nur auf Debian 10 mit updatedb aktualisiert wird. Ich habe einige Änderungen vorgenommen (einige Dateien und Verzeichnisse zwischen den beiden Daten erstellt). Und wie Sie sehen können, ist die Datenbank sehr schnell generiert. Es gibt also wirklich einen Unterschied in der Implementierung zwischen Linux und MacOS.
@youpilat13 Es ist kein Unterschied zwischen GNU/macOS und GNU/Linux. Ihre Debian-Installation verwendet mlocate , das eine völlig andere Implementierung als GNU locate ist, nicht so weit portiert und unter macOS AFAIK nicht verfügbar ist. Außerdem benötigen sowohl GNU locate als auch mlocate weniger als 1 Sekunde, um die Datenbank auf meinem Debian-System zu aktualisieren. Sie müssen die beiden Dienstprogramme auf demselben System vergleichen, um eine faire Bewertung zu erhalten.
Es scheint, dass die Antwort hier lautet, dass es tatsächlich keine Antwort gibt - oder zumindest keine, die keine große Anstrengung erfordert, um sie zu überwinden - habe ich das richtig verstanden? Ich habe meine Kopie locatevon MacPorts installiert - ich bin etwas enttäuscht, da MacPorts normalerweise einen Port nicht freigibt, der nicht richtig funktioniert.

/usr/libexec/locate.updatedbDie Apple-Version wird über ein Shell-Skript ausgeführt . Einige zusätzliche Pfade sind dort von der Suche ausgeschlossen. In Mojave sind dies

: ${PRUNEPATHS:="/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb"} # unwanted directories

PS: Ich habe kein Catalina, daher müssen Sie möglicherweise prüfen, ob andere Pfade ebenfalls ausgeschlossen werden müssen.

Vielen Dank für Ihre schnelle Antwort, aber das Problem betrifft das Stammverzeichnis "/", die Nachricht lautet: gfind: failed to read file names from file system at or below '/'.Ich habe versucht, mit Ihrem Vorschlag zu tun: sudo gupdatedb --prunepaths='/private/tmp /private/var/folders /private/var/tmp */Backups.backupdb /Volumes' --output=$HOME/locatedb_gupdatedbund ich erhalte die obige Fehlermeldung. Glaubst du, es ist ein sudo-Problem?
@ youpilat13 Es ist wahrscheinlich komplexer als es scheint, das Shell-Skript wird ausgeführt findund speist dann das Ergebnis in den locateb-Updater ein. Ich weiß nicht, wie die GNU-Version funktioniert, aber vielleicht können Sie einfach eine Kopie des Shell-Skripts verwenden, um die GNU-Version zu füttern.
Warum müssen Sie GNU locate verwenden, wenn bereits eines installiert ist?
@MarcWilson. Da ich erwarte, dass die GNU-Version das gleiche Verhalten wie auf Linux-Systemen hat, dh wenn wir bereits eine Datenbank haben, wird die aktuelle Datenbank aktualisiert und nicht gelöscht, wenn wir nach einigen Stunden der Verwendung einen weiteren updatedb-Befehl starten, um eine völlig neue zu erstellen. Dies ist Zeitverschwendung, um die gesamte Datenbank neu zu erstellen, und leider ist dies das dafaut-Verhalten des klassischen updatedb-Befehls von MacOS.
Dokumentation, die zeigt, dass dies das Verhalten von BSD locate ist?