Linux commando: locate
Je hebt een bestand nodig en je weet hoe het heet, maar je weet niet waar het staat. Het kan overal op een server met miljoenen bestanden staan. Je zou de hele schijf kunnen doorzoeken met find en wachten, of je kunt een programma gebruiken dat al weet waar alles staat en antwoord geeft nog voordat je klaar bent met typen. Dat programma is locate. Het doorzoekt de schijf helemaal niet; het zoekt het antwoord op in een index, en daarom lijkt het alsof het direct gebeurt.
1. De basis
De taak van locate is om bestanden op naam terug te vinden op het hele systeem, en dat snel. Je geeft het een stukje van een naam, en het print elk pad dat dat stukje bevat:
$ locate hosts
/etc/hosts
/etc/hosts.allow
/etc/hosts.deny
Het ene idee dat locate anders maakt dan elk ander zoekprogramma is dit: het kijkt niet naar het live bestandssysteem. In plaats daarvan scant een achtergrondtaak eens per dag de schijf en schrijft elk pad naar een compacte database. Als je locate uitvoert, leest het die database, nooit de schijf. Een voorbereide index doorzoeken is duizenden keren sneller dan mappen doorlopen, en daarom komt het antwoord terug op het moment dat je op Enter drukt.
Die snelheid heeft een eerlijke keerzijde: de database is maar zo actueel als de laatste update. Een bestand dat vijf minuten geleden is aangemaakt, staat er meestal nog niet in, en een bestand dat vanochtend is verwijderd, staat er misschien nog wel in. Voor de meeste zoekacties maakt dat niet uit, want je zoekt naar dingen die al een tijd bestaan: configuratiebestanden, logs, bibliotheken, foto's.
locate vindt geen bestanden; het zoekt ze op. Het antwoordt vanuit een dagelijkse index, niet vanaf de schijf voor je.
Naar bovenHet juiste mentale model:
locateis een kaartenbak, enfindis langs de planken lopen. De kaartenbak antwoordt in een seconde, maar is gisteravond gedrukt. Langs de planken lopen is trager, maar laat je precies zien wat er nu staat. Grijp eerst naar de kaartenbak, en loop alleen langs de planken als je accuraatheid van dit moment nodig hebt.
2. Waar komt de naam vandaan?
Net als find is de naam locate geen afkorting of grap. Het is het gewone Engelse werkwoord voor de taak: to locate, een bestand lokaliseren. De vroege Unix-auteurs hielden van korte, gewone woorden voor gewone taken, en korter dan dit wordt het woord niet.
Het interessante zit in de letter ervoor. Op een modern Linux-systeem heet het commando dat je uitvoert bijna nooit gewoon locate; het is een van een familie waarvan de eenletterige prefix de geschiedenis van de tool vastlegt:
| Naam | Prefix staat voor | Wat het toevoegde |
|---|---|---|
locate |
(het origineel) | De eerste index-gebaseerde bestandenzoeker |
slocate |
secure | Verbergt bestanden die de gebruiker niet mag zien |
mlocate |
merging | Hergebruikt de oude index en werkt alleen bij wat is veranderd |
plocate |
posting-list | Een trigram-index die veel sneller is |
Dus als je vandaag locate typt, voer je vrijwel zeker plocate of mlocate uit onder die vriendelijke naam. Elke prefix markeert een stap vooruit: maak het eerst veilig, maak dan de dagelijkse update goedkoop, maak vervolgens het zoeken zelf razendsnel. De prefix lezen is de changelog lezen.
3. Een korte geschiedenis
Het idee achter locate is ouder dan de meeste tools eromheen. Het werd geschreven door James A. Woods begin jaren tachtig en beschreven in een kort artikel over het snel terugvinden van bestanden. Zijn inzicht was eenvoudig en blijvend: in plaats van elke keer de schijf te doorzoeken, bouw je een gecomprimeerde index van alle bestandsnamen en doorzoek je die. Hij bedacht ook een slimme compressie, waarbij alleen het verschil tussen elk pad en het vorige wordt opgeslagen, zodat alle namen van het bestandssysteem in een klein bestand passen.
Die oorspronkelijke locate reisde mee met BSD Unix en werd later onderdeel van GNU findutils, hetzelfde pakket dat find levert. In de loop van de decennia werd het drie keer opnieuw uitgevonden, waarbij elke versie hetzelfde idee behield maar een echt probleem oploste:
| Tijdperk | Mijlpaal |
|---|---|
| begin jaren tachtig | James A. Woods schrijft de eerste locate: een gecomprimeerde index van elke bestandsnaam, doorzocht in plaats van de schijf |
| BSD / GNU | locate en updatedb worden geleverd met BSD en daarna met GNU findutils |
| eind jaren negentig | slocate (secure locate) voegt permissiecontroles toe zodat gebruikers alleen bestanden zien die ze mogen lezen |
| midden jaren 2000 | mlocate (merging locate) hergebruikt de oude database en scant alleen gewijzigde mappen opnieuw, waardoor de dagelijkse update snel wordt |
| 2020 | plocate van Steinar H. Gunderson introduceert een trigram-index; zoekacties die een seconde duurden, duren nu een milliseconde |
| Vandaag | plocate is de standaard op Debian en Ubuntu; mlocate blijft gangbaar op oudere en andere systemen |
De slocate-stap is het waard om even bij stil te staan. De allereerste locate had een privacylek: omdat het las uit een gedeelde index die door root was gebouwd, kon elke gebruiker de namen zien van bestanden overal op het systeem, zelfs in mappen die ze niet konden openen. slocate, en elke versie sindsdien, loste dit op door elk resultaat te toetsen aan de eigen permissies van de aanroeper. Daarom kan locate vandaag veilig draaien op een gedeelde server.
De versie op het referentiesysteem van dit artikel is plocate 1.1.19. Het is bewust niet compatibel met het oude BSD-locate-databaseformaat, en het gaat uit van UTF-8; in ruil daarvoor is het veel sneller dan alles ervoor. De commando's hieronder zijn ervoor geschreven, en geven aan waar mlocate zich anders gedraagt.
Installeren. Op veel systemen is locate er al, maar als het ontbreekt, is het pakket vernoemd naar de implementatie, meestal plocate:
$ sudo apt install plocate # Debian, Ubuntu
$ sudo dnf install plocate # Fedora
$ sudo pacman -S plocate # Arch Linux
Na het installeren voer je een keer sudo updatedb uit om de eerste database te bouwen. Vanaf dan houdt de dagelijkse timer hem actueel, en verwijst het gewone commando locate naar welke implementatie je ook hebt geinstalleerd.
4. Eenvoudige toepassingen
4.1 Het eenvoudigste gebruik
Geef locate een woord, en het print elk pad in de database dat dat woord ergens bevat:
$ locate sshd_config
/etc/ssh/sshd_config
/usr/share/man/man5/sshd_config.5.gz
Merk op dat het woord overal in het pad kan voorkomen, niet alleen aan het eind. Standaard wordt het patroon behandeld als een gewone deelreeks: locate hosts matcht /etc/hosts en ook /usr/lib/ghostscript, omdat de letters hosts in ghostscript zitten. Dit is de grootste verrassing voor nieuwe gebruikers, en sectie 5 laat zien hoe je het aanscherpt.
4.2 Hoofdletterongevoelig zoeken
Standaard is de match hoofdlettergevoelig. De vlag -i (kort voor ignore case) laat het matchen ongeacht hoofdletters, wat je wilt als je niet zeker weet hoe een bestand is genoemd:
$ locate -i readme
/opt/app/README.md
/usr/share/doc/bash/readme.txt
4.3 Tellen in plaats van opsommen
Als je alleen wilt weten hoeveel matches er zijn, print de vlag -c (kort voor count) een getal in plaats van een lange lijst:
$ locate -c .conf
1873
Dit is een snelle manier om de omvang van een resultaat in te schatten voordat je je scherm ermee overspoelt.
4.4 Zoeken naar meerdere woorden tegelijk
Je kunt meer dan een patroon meegeven. Dit is het ene gedrag waar plocate en het oudere mlocate echt verschillen, dus het is goed om te weten welke je hebt. Op plocate betekent meerdere patronen meegeven "match ze allemaal", als een AND:
$ locate nginx conf # plocate: paths containing BOTH "nginx" and "conf"
/etc/nginx/nginx.conf
/etc/nginx/conf.d/default.conf
Op mlocate betekent hetzelfde commando "match er een van" (een OR), en zou je -A (kort voor all) toevoegen om ze allemaal te vereisen. plocate accepteert -A ook, maar negeert het, omdat AND al de standaard is.
5. Gemiddelde toepassingen
5.1 Match alleen de bestandsnaam, niet de mappen
Omdat de standaardmatch naar het hele pad kijkt, kan een zoekactie matches oppikken die verstopt zitten in mapnamen hogerop. De vlag -b (kort voor basename) beperkt de match tot het laatste deel van het pad, de bestandsnaam zelf:
$ locate -b conf # too broad: "conf" appears in many folder names
$ locate -b '\.conf' # still substring, but only against file names
De mappen worden nog steeds in het resultaat geprint; ze mogen alleen niet langer de match veroorzaken. Dit is de schoonste manier om ruis te beperken als een veelvoorkomend woord in veel bovenliggende mappen voorkomt.
5.2 Gebruik jokertekens voor precieze matches
Zodra je patroon een shell-jokerteken bevat (*, ? of [ ]), stopt locate met het als deelreeks te behandelen en behandelt het het geheel als een glob-patroon. Dit is de truc om een zoekactie te verankeren. Vergelijk:
$ locate passwd # substring: matches anywhere, e.g. /etc/pam.d/passwd
$ locate '*/passwd' # glob: path must END in /passwd
/etc/passwd
/usr/bin/passwd
Zet een patroon met een jokerteken altijd tussen aanhalingstekens, zodat de shell het onaangeroerd aan locate doorgeeft in plaats van het uit te breiden tegen de huidige map. Uit de werking van glob-matching volgt een handige regel: om met een glob een gewone deelreeks te matchen moet je het tussen sterren zetten, '*naam*', want een kale glob is verankerd aan de uiteinden van het pad.
5.3 Toon alleen bestanden die nog bestaan
Omdat de database tot een dag oud kan zijn, kan het bestanden opsommen die sinds de laatste update zijn verwijderd. De vlag -e (kort voor existing) toetst elk resultaat aan de live schijf en laat de bestanden weg die weg zijn:
$ locate -e report.pdf # only paths that are actually on disk right now
/home/peter/report.pdf
Dit kost een beetje snelheid, want nu raakt locate wel het bestandssysteem aan om elke treffer te verifieren, maar het haalt de verrassing "bestand niet gevonden" weg als je iets met de resultaten doet.
5.4 Stop na een paar matches
Op een groot systeem kan een patroon duizenden paden matchen. De vlag -l (kort voor limit) stopt na een bepaald aantal, wat perfect is als je alleen wilt bevestigen dat iets bestaat of de eerste paar wilt bekijken:
$ locate -l 5 .service # first 5 matches, then stop
/etc/systemd/system/multi-user.target.wants/cron.service
/lib/systemd/system/cron.service
...
5.5 Geef resultaten veilig door aan een ander commando
Bestandsnamen op Linux kunnen spaties en zelfs regeleindes bevatten, wat een naieve pijp breekt. De vlag -0 (kort voor de null-scheiding) beeindigt elk resultaat met een onzichtbare null-byte in plaats van een regeleinde, en xargs -0 leest diezelfde scheiding:
$ locate -0 '*.bak' | xargs -0 ls -lh
Geen enkele bestandsnaam kan een null-byte bevatten, dus dit verwerkt elke rare naam zonder verrassing. Maak het je standaard zodra locate een ander commando via een pijp voedt.
6. Geavanceerde toepassingen
6.1 Waar de database vandaan komt: updatedb
Alles wat locate weet komt uit een bestand, de database, en een commando bouwt het: updatedb. Het draait als root zodat het de hele schijf kan zien, doorloopt het bestandssysteem en schrijft de index die locate later leest. Op een modern systeem draait het automatisch een keer per dag via een systemd-timer of een cron-taak:
$ systemctl list-timers | grep updatedb
plocate-updatedb.timer plocate-updatedb.service
Als je net bestanden hebt aangemaakt en er nu naar wilt zoeken, hoef je niet op de run van morgen te wachten. Trigger het zelf:
$ sudo updatedb # rebuild the index now, then locate sees new files
6.2 Bepalen wat wordt geindexeerd
Je wilt zelden elk pad in de index. Tijdelijke bestanden, netwerkschijven en virtuele bestandssystemen zouden hem alleen opblazen en de dagelijkse run vertragen. Het bestand /etc/updatedb.conf vertelt updatedb wat het moet overslaan:
PRUNEPATHS="/tmp /var/spool /media"
PRUNEFS="nfs cifs tmpfs proc sysfs devtmpfs"
PRUNENAMES=".git .svn .hg"
PRUNEPATHSsomt mappen op die volledig worden overgeslagen.PRUNEFSsomt bestandssysteemtypes op om over te slaan, zodat een aangekoppelde netwerkschijf of een virtuele/procnooit wordt doorlopen.PRUNENAMESsomt mapnamen op om over te slaan waar ze ook voorkomen, zoals.git-mappen.
Daarom vindt locate meestal geen bestand onder /tmp: dat pad wordt met opzet overgeslagen. Als een heel deel van je schijf onzichtbaar lijkt voor locate, is dit bestand de eerste plek om te kijken.
6.3 Een andere database doorzoeken
Je bent niet beperkt tot de systeemindex. De vlag -d (kort voor database) wijst locate naar een ander indexbestand, wat handig is voor een eigen index van een groot project of een externe schijf:
$ updatedb -l 0 -o photos.db -U /mnt/photos # build a private index
$ locate -d photos.db beach # search only that index
De -l 0 hierboven schakelt de permissie-zichtbaarheidsfunctie uit voor een eigen index die je zelf bouwt, en -U vertelt updatedb welke map het moet indexeren. Je kunt ook de omgevingsvariabele LOCATE_PATH instellen om automatisch een extra database aan elke zoekactie toe te voegen.
6.4 Echte reguliere expressies
Als globs niet expressief genoeg zijn, kan locate matchen met reguliere expressies. De vlag -r (kort voor regexp) gebruikt POSIX basic regex, en --regex gebruikt de extended variant, hetzelfde als grep -E:
$ locate --regex '/(nginx|apache2)/.*\.conf$'
/etc/nginx/nginx.conf
/etc/apache2/apache2.conf
Er zijn kosten die het waard zijn te begrijpen. Normaal springt plocate met zijn index meteen naar kandidaten en raakt het de database nauwelijks aan. Een regex kan die index niet gebruiken, dus dwingt het een trage lineaire scan van elke regel af. Gebruik regex als je het nodig hebt, maar geef de voorkeur aan een glob als een glob volstaat.
6.5 Waarom locate geen prive-bestanden lekt
De index wordt gebouwd door root en somt bestanden op die gewone gebruikers niet kunnen lezen. Hoe voorkomt locate dan dat het je de prive-paden van je buurman laat zien? Het draait met de setgid-bit, waardoor het de beveiligde index kan openen, maar voordat het een resultaat print controleert het of jij permissie hebt om dat pad te bereiken. Als je lees- en uitvoerrechten op de bovenliggende mappen mist, wordt de match stilletjes weggelaten. De kaartenbak is compleet, maar iedereen ziet alleen zijn eigen deel ervan.
7. Wat de meeste gebruikers niet weten
7.1 Hoe plocate zo snel is: de trigram-index
De oude locate was snel omdat het een klein bestand doorzocht in plaats van de schijf, maar het las dat hele bestand nog steeds elke keer. plocate doet dat vrijwel nooit. Zijn geheim is een trigram-index. Als de database wordt gebouwd, wordt elk pad in overlappende stukjes van drie letters gehakt: /etc/hosts levert /et, etc, tc/, c/h, /ho, enzovoort. Voor elk klein trigram slaat de index een lijst op van welke paden het bevatten, een posting list, en daar komt de "p" in plocate vandaan.
Als je zoekt naar hosts, breekt plocate je woord op in dezelfde trigrammen, zoekt het de korte posting lists op en snijdt ze om een kleine set kandidaatpaden te krijgen. Alleen die paar kandidaten worden volledig gecontroleerd. Het scant nooit de hele database, dus de zoekactie blijft snel zelfs als de index tot honderden megabytes groeit. De enige uitzondering is een patroon korter dan drie letters, dat geen volledig trigram heeft om op te zoeken en een scan afdwingt; daarom voelen heel korte zoekacties trager.
Het verschil is makkelijk zelf te voelen. Klok een locate-zoekactie tegen de vergelijkbare find-doorloop van de hele schijf:
$ time locate kernel
...
real 0m0.02s
$ time find / -name "*kernel*" 2>/dev/null
...
real 0m21.7s
Beide geven dezelfde bestanden terug, maar locate leest een kant-en-klare index terwijl find elke map op het systeem opent. Op een grote server is dat het verschil tussen een onmiddellijk antwoord en een koffiepauze.
7.2 Weten waar locate ophoudt
Een deel van expertise is weten welke tool het overneemt als locate zijn grens bereikt:
| Behoefte | Gebruik | Waarom |
|---|---|---|
| Een bestand vinden dat seconden geleden is aangemaakt | find |
locate weet alleen wat de laatste dagelijkse updatedb heeft vastgelegd |
| Zoeken op grootte, leeftijd, eigenaar of permissie | find |
De index slaat alleen namen op, geen metadata |
| Zoeken binnen bestandsinhoud | grep |
locate matcht padnamen, nooit wat er in een bestand staat |
| Het programma achter een commando vinden | which / type |
Ze zoeken een naam op in $PATH, wat daar precies is wat je wilt |
De gezonde gewoonte is om eerst naar locate te grijpen voor elke "waar staat dat bestand?"-vraag, want het antwoordt onmiddellijk, en pas terug te vallen op find als je actualiteit nodig hebt of een test op grootte, leeftijd of permissies.
8. Beste werkwijzen
- Grijp eerst naar
locate, dan naarfind. Voor een simpele "waar staat dit bestand"-vraag is het veel sneller; gebruikfindals je live resultaten of metadatatests nodig hebt. - Voer
sudo updatedbuit na grote wijzigingen. Als je net software hebt geinstalleerd of bestanden hebt aangemaakt enlocateze niet ziet, is de index gewoon verouderd. Ververs hem. - Zet patronen met jokertekens tussen aanhalingstekens. Schrijf
locate '*/passwd', nietlocate */passwd, anders breidt de shell het patroon uit voordatlocatehet ziet. - Gebruik
-bom ruis te beperken. Als een veelvoorkomend woord in veel mapnamen verstopt zit, match dan alleen de basename. - Voeg
-etoe als je iets met de resultaten gaat doen. Het laat paden weg die niet meer bestaan, zodat je geen verwijderd bestand najaagt. - Geef de voorkeur aan een glob boven een regex. Een glob gebruikt de snelle index;
-ren--regexforceren een volledige scan. - Gebruik
-0 | xargs -0in pijpen. Het is de enige veilige manier om resultaten met spaties of regeleindes aan een ander commando door te geven.
Als je alle details nodig hebt, is de documentatie een commando ver weg:
$ man locate # the manual for your locate (often plocate or mlocate)
$ locate --help # a quick summary of every option
$ man updatedb # how the index is built and scheduled
Naar boven9. Veelgemaakte fouten
9.1 Vier veelvoorkomende mythes
| Mythe | Werkelijkheid |
|---|---|
"locate doorzoekt mijn schijf." |
Het leest een database die eens per dag door updatedb wordt gebouwd, nooit de live schijf. |
"Als locate het niet kan vinden, is het bestand weg." |
Het kan gewoon nieuwer zijn dan de laatste index, of in een overgeslagen pad zoals /tmp staan. Voer updatedb uit. |
"locate name matcht alleen bestanden die name heten." |
Het matcht name als deelreeks overal in het pad. Gebruik een glob of -b om het te versmallen. |
"locate en find doen hetzelfde." |
Zelfde doel, tegengestelde methodes: locate is een snelle verouderde index, find is een live maar tragere doorloop. |
9.2 Andere valkuilen om te vermijden
- Gloednieuwe bestanden verwachten. Een bestand dat na de laatste
updatedbis aangemaakt, verschijnt pas als de index ververst. Dit is veruit de meest voorkomende verwarring. - Overgeslagen paden vergeten.
/tmp, netwerkschijven en virtuele bestandssystemen worden met opzet uitgesloten in/etc/updatedb.conf, duslocatezal ze nooit opsommen. - Jokertekens zonder aanhalingstekens. Een
*zonder aanhalingstekens wordt eerst door de shell uitgebreid, duslocatezoekt uiteindelijk naar het verkeerde. - Te snel naar regex grijpen.
-ren--regexschakelen de snelle index uit en scannen alles. Een glob is meestal genoeg en veel sneller. - Aannemen dat plocate en mlocate het eens zijn over meerdere patronen. Meerdere patronen betekenen AND op
plocatemaar OR opmlocate. Controleer welke je hebt voordat je het resultaat vertrouwt. locateals enige controle draaien voor je iets verwijdert. De lijst kan verouderd zijn. Bevestig met-e, of metls, voordat je iets doet.
10. Samenvatting
Het commando locate vindt bestanden op naam op het hele systeem vrijwel onmiddellijk, door ze op te zoeken in een voorbereide index in plaats van de schijf te doorzoeken.
locateleest een database die eens per dag doorupdatedbwordt gebouwd; het is snel omdat het nooit het live bestandssysteem doorloopt.- De keerzijde is actualiteit: gloednieuwe bestanden ontbreken tot de index bijwerkt, dus voer
sudo updatedbuit als je actuele resultaten nodig hebt. - De naam die je typt is meestal
plocateofmlocate; de prefix legt de geschiedenis van de tool vast, van secure naar merging naar posting-list. - Patronen matchen standaard als deelreeks; een jokerteken maakt van het patroon een verankerde glob, en
-bbeperkt de match tot de bestandsnaam. - Alledaagse vlaggen:
-i(hoofdletters negeren),-c(tellen),-e(alleen bestaande),-l(limiet),-0(veilig doorgeven). - Bepaal wat wordt geindexeerd via
/etc/updatedb.conf, en gebruikfindals je actualiteit, metadata of zoeken in inhoud nodig hebt.
Dit is het overzicht dat het waard is om te bewaren:
locate hosts paths containing "hosts" anywhere
locate -i readme same, ignoring upper/lower case
locate -c .conf count the matches instead of listing them
locate nginx conf plocate: paths matching BOTH words
locate -b '\.conf' match the file name only, not the folders
locate '*/passwd' glob: path must end in /passwd
locate -e report.pdf only results that still exist on disk
locate -l 5 .service stop after the first 5 matches
locate -0 '*.bak' | xargs -0 ls -lh safe pipe for odd names
locate --regex '\.log$' match with an extended regular expression
sudo updatedb rebuild the index now
man updatedb how the index is built and pruned
Als locate eenmaal onderdeel van je gewoontes is, voelt een grote server niet meer als een doolhof. Je stopt met gissen waar dingen staan en vraagt het gewoon, en het antwoord komt voordat je de gedachte hebt afgemaakt. Als je servers zijn uitgegroeid tot iets waar niemand nog echt de weg in vindt, is dat op orde brengen, en het snel en netjes houden, precies het soort werk waar ik bij help.


Peter is Joomla specialist en Linux admin voor snelle, veilige en schaalbare websites.


