CertGrid CertGrid
Hands-on Lab·Linux Foundation Certified System Administrator

find, locate and the two kinds of link

find is the tool the exam reaches for whenever a task says "all files that...", and its two -exec forms behave differently enough to matter. This guide covers searching by name, type, size, time and permission, the difference between ; and +, locate and why its answer can be wrong, and the two kinds of link - including what happens to each when the original is deleted.

Essential Commands Guide 10 of 38 Intermediate

GNU findutils. plocate is not installed on Ubuntu 26.04 by default - the capture installs it. -printf and -xtype are GNU extensions and are on both exam images.

Everything on this page runs on the one Ubuntu host.
Server NameIP AddressOSRolesCPURAMHDD
LFCS-A01192.168.0.70Ubuntu 26.04 LTSPrimary host - most guides run only here2 Core4 GB50 GB

This guide includes

Use this because find is what the exam reaches for whenever a task says "all files that...". This matters because -exec ; and -exec + run the same command completely differently - once per file, or once for all of them.

Before you start

  1. find, by name and by type

    A small tree, searched four ways.

    bash Example session
    cd ~/ess/f && find . -name '*.log' | sort./app/logs/big.log./app/logs/old.log./app/logs/small.logcd ~/ess/f && find . -type d | sort; echo "---"; find . -type f | wc -l; echo "---"; find . -iname '*.LOG' | wc -l../app./app/conf./app/logs./tmp---5---3cd ~/ess/f && find . -maxdepth 2 -type f | sort; echo "--- maxdepth stops it walking the whole tree"./tmp/scratch--- maxdepth stops it walking the whole treecd ~/ess/f && find . -name '*.log' -not -name 'old*' | sort; echo "---"; find . \( -name '*.conf' -o -name '*.log' \) -type f | wc -l./app/logs/big.log./app/logs/small.log---4

    Expected resultThree .log files; five directories; -maxdepth 2 finding only ./tmp/scratch; and -not excluding old.log.

    Success conditionYou can find files by name and shape.

  2. By size, by time, by permission

    The three tests that answer real questions - and one that finds nothing.

    bash Example session
    cd ~/ess/f && find . -type f -size +1k | sort; echo "--- and the sizes for comparison:"; find . -type f -printf '%6s %p\n' | sort -rn--- and the sizes for comparison:   292 ./app/logs/big.log     2 ./app/logs/small.log     2 ./app/conf/app.conf     0 ./tmp/scratch     0 ./app/logs/old.logcd ~/ess/f && find . -mtime +5 -type f; echo "--- older than 5 days"; find . -mtime -1 -type f | wc -l; echo "--- modified in the last day"./app/logs/old.log--- older than 5 days4--- modified in the last daycd ~/ess/f && find . -type f -perm 600; echo "--- exactly 600"; find . -type f -perm -u=w | wc -l; echo "--- has at least user-write"./app/conf/app.conf--- exactly 6005--- has at least user-writecd ~/ess/f && find . -newer app/logs/small.log -type f | sort; echo "--- newer than a reference file"./tmp/scratch--- newer than a reference file

    Expected result-size +1k matching nothing (the biggest file is 292 bytes); -mtime +5 finding the 10-day-old file; -perm 600 finding the config.

    Success conditionYou can find files by their metadata.

  3. -exec, and the difference between ; and +

    The same search, running the same command two ways.

    bash Example session
    cd ~/ess/f && find . -name '*.log' -exec wc -l {} \; | sort -rn100 ./app/logs/big.log1 ./app/logs/small.log0 ./app/logs/old.logcd ~/ess/f && find . -name '*.log' -exec wc -l {} + ; echo "--- with + it runs ONCE with all the arguments, so wc prints a total"  0 ./app/logs/old.log100 ./app/logs/big.log  1 ./app/logs/small.log101 total--- with + it runs ONCE with all the arguments, so wc prints a total

    Expected resultWith \;: three separate wc runs and no total. With +: one run and a 101 total line.

    Success conditionYou can choose the right -exec form.

  4. -print0, for the filenames you did not choose

    Handing find's results to another command safely.

    bash Example session
    cd ~/ess/f && find . -name 'scratch' -delete && find . -name 'scratch' | wc -l; echo "--- -delete needs no -exec rm"0--- -delete needs no -exec rmcd ~/ess/f && find . -type f -name '*.log' -printf '%p %TY-%Tm-%Td %s\n' | sort./app/logs/big.log 2026-08-29 292./app/logs/old.log 2026-08-19 0./app/logs/small.log 2026-08-29 2

    Expected result-delete removing the file with no -exec; and -printf producing path, date and size in one line each.

    Success conditionYou can pass results to another tool without breaking on spaces.

  5. locate, which reads an index instead of the disk

    Not installed by default. Then indexed, then queried - and then caught out.

    bash Example session
    command -v locate plocate mlocate updatedb 2>/dev/null; echo "--- (nothing above means not installed)"/usr/bin/locate/usr/bin/plocate/usr/bin/updatedb--- (nothing above means not installed)sudo apt-get install -y -qq plocate 2>&1 | tail -1; command -v locate updatedb/usr/bin/locate/usr/bin/updatedbsudo updatedb && locate -n 3 nginx.conf 2>&1 | head -4; echo "---"; locate -c '*.service' 2>&1 | tail -1---532cd ~/ess/f && touch brand-new-file.txt && locate brand-new-file.txt 2>&1 | head -2; echo "--- not in the index yet, because the index is a snapshot"; sudo updatedb && locate brand-new-file.txt | head -1--- not in the index yet, because the index is a snapshot/home/sysadmin/ess/f/brand-new-file.txt

    Expected resultNothing installed at first; then locate -c '*.service' counting 554; and a brand-new file not found until updatedb runs again.

    Success conditionYou know when to trust locate and when not to.

  6. The two kinds of link

    A hard link and a symlink to the same file, side by side.

    bash Example session
    cd ~/ess/f && printf 'original\n' > target.txt && ln target.txt hard.txt && ln -s target.txt soft.txt && ls -li target.txt hard.txt soft.txt789207 -rw-rw-r-- 2 sysadmin sysadmin  9 Aug 29 09:41 hard.txt789208 lrwxrwxrwx 1 sysadmin sysadmin 10 Aug 29 09:41 soft.txt -> target.txt789207 -rw-rw-r-- 2 sysadmin sysadmin  9 Aug 29 09:41 target.txtcd ~/ess/f && stat -c '%h links, inode %i, %F, %n' target.txt hard.txt soft.txt2 links, inode 789207, regular file, target.txt2 links, inode 789207, regular file, hard.txt1 links, inode 789208, symbolic link, soft.txt

    Expected resulttarget.txt and hard.txt sharing inode 403889 with a link count of 2; soft.txt on its own inode, 1 link, and 10 bytes - the length of the target's name.

    Success conditionYou can tell the two apart from ls -li.

  7. And what happens when the original goes

    Delete target.txt and ask both links for the data.

    bash Example session
    cd ~/ess/f && rm target.txt && echo "--- target removed:"; cat hard.txt; echo "--- the hard link still has the data"; cat soft.txt 2>&1 | tail -1; echo "--- the symlink is now dangling"--- target removed:original--- the hard link still has the datacat: soft.txt: No such file or directory--- the symlink is now danglingcd ~/ess/f && ls -l soft.txt; find . -xtype l; echo "--- find -xtype l lists broken symlinks"lrwxrwxrwx 1 sysadmin sysadmin 10 Aug 29 09:41 soft.txt -> target.txt./soft.txt--- find -xtype l lists broken symlinkscd ~/ess/f && ln -s /etc/hostname abs.txt && readlink abs.txt; readlink -f abs.txt; echo "--- readlink -f resolves the whole chain"/etc/hostname/etc/hostname--- readlink -f resolves the whole chain

    Expected resultcat hard.txt printing original; cat soft.txt giving No such file or directory; and find -xtype l listing ./soft.txt.

    Success conditionYou can find and reason about broken links.

  8. And what a hard link cannot do

    Two limits, both of which the symlink does not have.

    bash Example session
    cd ~/ess/f && ln app/logs/big.log hardsame 2>&1 | tail -1 && echo "same filesystem: fine"; ln /etc/hostname /tmp/../home/sysadmin/ess/f/hardcross 2>&1 | tail -1; ln -s /etc/hostname softcross && echo "and a symlink crosses anything"same filesystem: fineln: failed to create hard link '/etc/hostname' => '/tmp/../home/sysadmin/ess/f/hardcross': Permission deniedand a symlink crosses anythingcd ~/ess/f && ln app 2>&1 | tail -1; ln -s app dirsoft && ls -ld dirsoft; echo "--- you cannot hard-link a directory, but you can symlink one"ln: app: hard link not allowed for directorylrwxrwxrwx 1 sysadmin sysadmin 3 Aug 29 09:41 dirsoft -> app--- you cannot hard-link a directory, but you can symlink one

    Expected resultA hard link within the filesystem working; a hard link to a directory refused; and a symlink doing both.

    Success conditionYou know which kind of link to reach for.

Troubleshooting

Official sources