Signal9Signal9 — home
online
all lessons

Why & When: find vs grep, and 'Everything Is a File'

Beginner30 min5 steps
What you'll learn
  • Choose find vs grep correctly every time: filesystem search vs content search
  • Use grep -l to cross the bridge — search content but get back a filename
  • Explain 'everything is a file' and read kernel state (/proc) and devices (/dev) with ordinary tools
  • Answer 'what kind of file is this?' with file, stat, ls -l, and type
  1. Doing vs. understanding

    See why the mental model matters more than memorizing commands.

    Most beginners collect commands like trading cards: ls, cd, grep, find… and then freeze when a real task doesn't match a card they memorized. The people who are fast on Linux aren't the ones who memorized more — they carry a small set of mental models that tell them which tool the situation calls for.

    This lesson installs three of those models: find vs grep (the single most common mix-up), everything is a file (why the same handful of tools work everywhere), and what kind of file is this? (never trust a filename).

  2. find vs grep: two verbs, never interchangeable

    Reach for find when you want a file, grep when you want what's inside one.

    Here is the whole distinction, and it never changes:

    • `find` searches the _filesystem_ for files, by their name, type, size, age, owner, or permissions. It answers "where is the file?" It does not look inside files.
    • `grep` searches _inside_ files for a line of text. It answers "what's in the file?" It does not hunt for filenames.

    A quick self-check while typing: am I describing a filename pattern, or a word I expect to find in the content? Filename → find. Content → grep.

    find /etc -name '*.conf'
    /etc/ssh/ssh_config.d/50-redhat.conf
    /etc/ld.so.conf
    /etc/rsyslog.conf
    /etc/logrotate.conf
    -name
    match the filename against a glob pattern (*.conf)
    A find job: locate files by NAME anywhere under /etc. Grep literally cannot do this — it has no concept of 'files named .conf'. Quote '.conf' so the shell hands the pattern to find instead of expanding it first.

    Notice the word name is only one of find's powers. Because it searches the filesystem, it can match on any attribute the filesystem records — and that's what makes it far more than a filename lookup. Hunt for files by age, size, owner, or permissions and you're using find the way admins actually do:

    find /var/log -name '*.log' -mtime -1 -size +1M
    /var/log/app.log
    /var/log/nginx/access.log
    -mtime -1
    modified less than 1 day (24h) ago (-1 = within, +1 = older than)
    -size +1M
    larger than 1 megabyte (+ = bigger than, - = smaller than)
    Locate log files modified in the last day AND bigger than a megabyte — a real 'what filled up my disk overnight?' query. grep can't express any of this; none of it is about content, all of it is about the file's metadata. Stacked conditions like these are find's superpower.

    Example — not runnable on your lab box

    grep CRITICAL /var/log/system.log
    2026-07-01 08:01:12 CRITICAL out of memory, killing worker 4
    2026-07-01 08:05:31 CRITICAL replication lag exceeded threshold
    A grep job: pull the lines that CONTAIN the word CRITICAL out of a file's contents. Find can't do this — it never opens the file. Same machine, opposite question.
    grep -rl 'debug = true' /etc --include='*.conf'
    /etc/myapp/app.conf
    -r
    recurse into a directory tree
    -l
    print the matching FILE's name, not the matching line
    --include
    only search files whose name matches this glob
    The bridge between the two: grep -l searches CONTENT but reports the FILE that matched, not the line. -r recurses a directory tree; --include scopes it to real config files so a stray .txt saying the same thing doesn't sneak in. This is how you answer 'which file contains X?'.

    Check yourself

    You need to locate every file named *.log under /var. Which tool?

  3. Everything is a file

    Understand why the same cat/stat/ls work on documents, kernel state, and devices alike.

    Linux's defining idea: almost everything is presented as a file in the filesystem. Not just your documents, but:

    • directories (a file that lists other files),
    • devices — your disk, terminal, and /dev/null all appear under /dev,
    • live kernel state — /proc and /sys are virtual: reading them asks the kernel a question right now,
    • pipes and sockets used for inter-process communication.

    Because they're all 'files', one small toolset reads them all — cat, stat, ls, grep. You don't learn a new API per device; you cat it.

    cat /proc/loadavg
    0.14 0.09 0.06 1/213 2048
    /proc/loadavg isn't a file on any disk — the kernel generates it the instant you read it. Yet plain cat works. That's 'everything is a file' in action: kernel state exposed through the filesystem.
    stat -c %F /dev/null
    character special file
    -c %F
    print just the human-readable file type
    /dev/null is a device, not a document — stat reports its type as a 'character special file'. Same stat command you'd run on a text file; the metadata just says something different.

    Check yourself

    Reading which top-level virtual directory shows you live kernel/process state as files?

  4. What kind of file is this?

    Identify a file's true type from content and metadata, never from its name.

    A filename is just a label — Linux doesn't care about the .txt or .sh on the end. data could be text, a JPEG, or a program. Four tools tell you what something really is:

    • `file` — sniffs the actual bytes and names the type ('ELF 64-bit executable', 'ASCII text', 'symbolic link').
    • `stat` — the metadata: type, size, owner, timestamps.
    • `ls -l` — its first character is the type flag: - regular, d directory, l symlink, c char device, b block device. It also shows a symlink's -> target.
    • `type` / `which` / `command -v` — for commands: is ll a real program, a shell builtin, or an alias?
    file /bin/ls /etc/hostname /etc/rc0.d
    /bin/ls:       ELF 64-bit LSB pie executable, x86-64
    /etc/hostname: ASCII text
    /etc/rc0.d:    symbolic link to ../rc.d/rc0.d
    Three different real types, discovered by content — a compiled program, plain text, and a symlink — regardless of their names. This is why you 'ask the file what it is' instead of guessing from the extension.
    type -a ls
    ls is aliased to `ls --color=auto'
    ls is /usr/bin/ls
    -a
    show ALL meanings (alias, builtin, and every binary on PATH)
    For commands, type answers 'what will run when I type this?' Here ls is both an alias AND a real binary — the alias wins. which alone would only show the binary and miss the alias.

    Check yourself

    A file named 'report.txt' — how do you check whether it's REALLY plain text and not, say, a disguised binary?

  5. Now do it — put all three models to work in your live terminal

    Run one command per model on your own machine so the distinctions become reflex.

    Three tiny experiments, one per model. Do them in order — each one is the moment the idea stops being abstract. First, the find vs grep split: locate config files by name, then look inside config files for a word. Feel your brain pick the right verb each time.

    find /etc -maxdepth 1 -name '*.conf'; echo '--- vs ---'; grep -rl 'path' /etc --include='*.conf' 2>/dev/null | head
    The left half asks 'where are the .conf files?' (find, by name). The right half asks 'which .conf files mention path?' (grep -rl, by content). Same directory, two different questions — and you reached for a different tool for each without thinking. That's the model working. (Your terminal supplies the output.)
    cat /proc/loadavg; cat /proc/uptime
    Now feel everything is a file: cat two virtual files and watch the kernel answer with live numbers that exist nowhere on disk. Run them twice a few seconds apart — uptime's counter moves, proving you're reading the system right now, not a stored file.
    file $(which bash); file /etc/hostname
    Finally, what kind of file is this? Ask file about a program and a text file back to back. One comes back 'ELF 64-bit executable', the other 'ASCII text' — types discovered from the bytes, not the names. You just used all three models in under a minute; string them together and no unfamiliar file or directory can intimidate you.
Recap
  • find = search the filesystem for files (name/type/size/owner). grep = search inside files for text. If you're typing a filename pattern it's find; if you're typing a word to look for it's grep.
  • grep -l (and grep -rl) bridges the two: it searches content but hands you back the matching file's name.
  • Everything is a file — directories, devices (/dev), and live kernel state (/proc, /sys) all appear in the filesystem, so one toolset (cat/stat/ls/grep) reads them all.
  • Never trust a filename: file sniffs content, stat/ls -l read metadata and the type character, and type/which resolve what a command actually is.
Which tool for which question?
The question you're askingReach for
Where is the file named X?find -name
Which lines inside this file say X?grep X file
Which file contains X?grep -rl X dir/
What type of thing is this?file / stat / ls -l
What runs when I type this command?type -a / command -v
What's the current kernel/process state?cat /proc/... , /sys/...