Learn › Linux Foundations › Search
updatedb - a hands-on Linux lab on a real virtual machine.
Write the database that locate reads: build a private snapshot of the archive with updatedb (-U, -o, -l 0), prove it with a readback, then watch it go stale when the disk changes and catch it up with a rebuild. All in the practice terminal.
In the last lesson you read the archive's saved list with locate, and every lookup came back in an instant. But that lesson left two loose ends hanging. First: the database file ~/archive.db was already sitting there, prebuilt. Who wrote it? Second, and sharper: locate reads a saved list, never the disk. So what happens the moment the disk changes and the list does not?
Here is the trap you will walk into today, on purpose. A brand-new file really exists inside ~/archive. It is on the disk right now. And locate will look straight at your query and print nothing at all. By the end of this lesson you will know exactly why, and you will fix it with the one command this lesson is about: updatedb, the command that writes the list.
The black boxes in this lesson are a practice terminal: a safe sandbox that only checks the one command each step teaches, so you cannot break anything. updatedb ships in the same mlocate package as locate, which is not part of a bare Linux install, so the practice terminals replay its real output here. On the real machine at the end of the module, the mission installs mlocate for you before you run these.
updatedb is the other half of locate. It walks a directory tree once, records every path it finds, and writes them all into a database file. That one walk is the expensive part, and updatedb pays it up front, so every locate afterwards just reads the finished list.
That split is the entire design. locate never touches the disk because updatedb already did. One command writes the list, the other reads it, and the pair only works when both do their job.
The idea is old and battle-tested. It traces back to a 1983 Unix tool called fast find, whose author made one bet: do the slow disk crawl once, overnight, so every daytime lookup is free. Most Linux systems still run updatedb on a nightly schedule for exactly that reason.
You are going to build a small private database of just ~/archive, written to your home folder: the very same ~/archive.db the last lesson read. Three flags shape exactly what gets written:
-U ~/archive sets the one subtree to scan (short for update-from). It keeps the database small and bounded, only ~/archive.-o ~/archive.db sets the output file (short for output). Writing to your own file means you do not need to be root and you do not touch the system-wide database.-l 0 turns off the visibility check (short for require-visibility) so you can read back your own private database in this sandbox.Before you run it, decide: when the build succeeds, what will updatedb print? A summary? A count of files scanned? Lock in your guess, then type this exact command and press Enter:
updatedb -l 0 -U ~/archive -o ~/archive.db
prompt: student@linuxcamp:~$ answer: updatedb -l 0 -U ~/archive -o ~/archive.db output: hint: Type updatedb, then the three flags in order: -l 0, then -U ~/archive, then -o ~/archive.db
Nothing printed. If you guessed a summary, that silence is the surprise: updatedb says nothing when it works, the same way cd says nothing when it moves you. Behind that blank line, it walked all of ~/archive one time and wrote every path it saw into ~/archive.db. That file is now a frozen snapshot of the archive. You paid the walking cost once, here. Every locate from now on reads this list instead of the disk.
A silent command deserves a check. The cleanest proof that your build worked is to read something back out of the new database with the locate you already know, pointing at your private file with -d, exactly as in the last lesson.
The archive holds exactly two .csv data files, both under reports/2025, and you never looked them up before. Before you run this, decide: will the two paths come off the live disk, or out of the file you wrote a moment ago?
locate -d ~/archive.db '*.csv' | sort
prompt: student@linuxcamp:~$ answer: locate -d ~/archive.db '*.csv' | sort output: /home/student/archive/reports/2025/data.csv /home/student/archive/reports/2025/metrics.csv hint: The readback shape from the locate lesson: locate -d ~/archive.db '*.csv' then a padded pipe and sort
Two paths, straight out of ~/archive.db. locate never walked the disk; both lines came from the snapshot you wrote seconds ago. That readback is your proof: the build worked, and the database holds the whole archive. From here on, remember from the locate lesson that the * pattern anchors to the end and | sort keeps the order stable; this lesson will not reteach the query side.
Now the trap from the opening. Your snapshot froze the moment updatedb finished. Since then, the disk has moved on: a brand-new file, ~/archive/notes.md, has just been created inside the archive. It is really there, on the disk, right now.
Before you run this, decide: the file genuinely exists, so will locate print its path?
locate -d ~/archive.db notes.md
prompt: student@linuxcamp:~$ answer: locate -d ~/archive.db notes.md output: hint: Run locate -d ~/archive.db notes.md and watch closely what comes back
Nothing, even though the file is really on the disk. This is the file the list cannot see. locate is not broken and it is not lying; it is faithful to its snapshot. notes.md did not exist when updatedb last ran, so it is not in the list. You already met the silent empty result in the locate lesson, where it meant no match. This is the second, sneakier way to earn that silence: the file is real, just younger than the list. That is the one trade-off you accept for the speed.
The fix is the command you started with. Run updatedb again and it re-walks ~/archive, sees everything that exists right now, notes.md included, and writes a fresh snapshot.
Before you run it, decide: will updatedb complain that ~/archive.db already exists, or quietly replace it?
updatedb -l 0 -U ~/archive -o ~/archive.db
prompt: student@linuxcamp:~$ answer: updatedb -l 0 -U ~/archive -o ~/archive.db output: hint: The same build command as before: updatedb -l 0 -U ~/archive -o ~/archive.db
Silent again: it quietly overwrote the old snapshot, no complaint, no prompt. The database is now current, and the same locate -d ~/archive.db notes.md that came back empty a moment ago would now print /home/student/archive/notes.md.
Stop and notice what you just did, because it is the whole job of this command. Miss, rebuild, find: that round trip is the rhythm of updatedb, and you have now driven every part of it. find re-walks the live disk every time, always current but slower. locate reads a prebuilt list, instant but only as fresh as its last updatedb. You now hold both halves of the fast side.
Scaffolding off. No command is shown from here on.
Make the rebuild a habit. It is the end of the working day, the archive has been busy, and you want tomorrow's first lookup to be current. Rebuild your private database: scan only the ~/archive subtree, write the result to ~/archive.db, and keep the visibility check off so you can read your own file.
prompt: student@linuxcamp:~$ answer: updatedb -l 0 -U ~/archive -o ~/archive.db output: hint: Three flags in order: -l 0 for visibility, -U for the subtree to scan, -o for the output file
Straight from memory, and silence again means success. Those three flags are the whole private-database recipe: -U picks what to scan, -o picks where the list lands, -l 0 keeps your own file readable. That exact command is what a real machine will ask of you with no prompt in sight.
One more, still no command shown. Prove the fresh database is fully loaded by asking it a question with a one-number answer: how many .txt files does the snapshot hold? Use the counting flag from the locate lesson, pointed at your private database.
prompt: student@linuxcamp:~$ answer: locate -d ~/archive.db -c '*.txt' output: 4 hint: -d picks the database and -c counts the matches; the pattern is '*.txt' in single quotes
Just 4, the four .txt files across the archive, counted out of the list you built and rebuilt yourself. Notice what happened across these two challenges: one command from this lesson wrote the snapshot, one flag from the last lesson audited it. updatedb and locate are two halves of a single tool, and you just drove both from memory.
You earned this cheat sheet. Every row is something you just did to ~/archive.db:
The one rule that ties it together: locate is fast because it reads a list, and a list only knows what existed when updatedb last ran. Rebuild it whenever the disk has changed. An empty locate result means either no match or a snapshot that has not caught up yet, and updatedb fixes the second one.
On a real system, updatedb for the whole disk usually runs on a schedule in the background, so the system-wide locate is refreshed for you overnight. When you cannot find a file you just created, a stale database is the usual reason, and re-running updatedb is the cure.
The practice terminal has shown you the rhythm: write the list with updatedb, read it back to prove it, and rebuild the moment the disk moves on. Every command you typed drills exactly what the search mission asks for.
The Search module ends with one real Linux machine, and that is where you run this for real. In the Search capstone mission, a VM boots just for you on this same ~/archive fixture. The mission installs mlocate, then hands you objectives that use exactly what you just practiced. You build the private database with -U, -o, and -l 0, then audit it with the locate queries from the last lesson. One difference from here: the lab shows no commands. You read the objective, you recall the flags, you type them. That recall is what makes it stick.
Finish the other Search lessons, then go build the index for real.
Practice updatedb in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.