Learn › Linux Foundations › Reading Files
file - a hands-on Linux lab on a real virtual machine.
Identify what a file truly is by its contents, not its name, with the file command. Tell ASCII text from raw data from a directory, check several files at once, strip the path with -b, and read the standardized MIME type with -i, all on the intercept fixture.
A file's name is just a label a person typed. The part after the dot, like .txt or .bin, is called the extension, and Linux does not enforce it at all. You can name a photo notes.txt or name a plain letter data.bin, and nothing stops you. So the name tells you what someone *called* the file, never what is truly inside it.
There is one command whose entire job is to answer the real question: what kind of file is this, actually? It is called file, and it ignores the name completely. It opens the file, reads the first bytes of the content, and tells you the type it finds. That is the one command this lesson is about, start to finish.
The black boxes in this lesson are a practice terminal: a safe sandbox, not the real machine. Each box replays the real output of the one command the step teaches, so you cannot break anything. file only ever reads a file's bytes to identify it; it never changes, moves, or deletes anything. You run all of this for real on a live machine at the end of the module.
You are on a box called the intercept station, with a folder named intercept in your home directory. Inside logs is a plain-text log named messages.log. Point file at it and read the verdict:
file ~/intercept/logs/messages.log
prompt: student@linuxcamp:~$ answer: file ~/intercept/logs/messages.log output: /home/student/intercept/logs/messages.log: ASCII text hint: Type file, a space, then the path to the log: file ~/intercept/logs/messages.log
file printed the path, a colon, then its verdict: ASCII text. ASCII is the oldest, simplest way of storing plain English characters, one byte per letter, digit, or space. So file is telling you this is readable text you could safely open with a reader like cat or less. Notice it never mentioned .log. It reached inside and judged the bytes, not the name.
file works by looking at the opening bytes of a file and matching them against a big built-in list of known patterns. Those tell-tale opening bytes are often called a magic number: a fixed signature near the start of a file that says "I am a PNG image" or "I am a compressed archive." When nothing matches a known signature, file falls back to a simpler question. Are these bytes all readable characters, or not?
Because it reads content and not the label, renaming a file cannot fool it. A text file called secret.bin still comes back as text; a picture called report.txt still comes back as an image. The extension is a hint for humans, but file checks the truth underneath.
This is why file is the safe first move on anything unfamiliar. Before you cat a mystery file and risk spraying unreadable bytes across your screen, run file on it and let it tell you whether the thing is even text.
file does not only pick a broad category. When a file is text, it often adds a note about a detail it spotted. A common one is about the newline: the invisible character that marks the end of a line. Most text files end their last line with one. Some do not.
In the intel room is a one-line note, notes.md, that was saved with no final newline. Run file on it and read the extra note it adds:
file ~/intercept/intel/notes.md
prompt: student@linuxcamp:~$ answer: file ~/intercept/intel/notes.md output: /home/student/intercept/intel/notes.md: ASCII text, with no line terminators hint: Type file, a space, then the note path: file ~/intercept/intel/notes.md
Still ASCII text, but now with a tail: with no line terminators. A "line terminator" is that end-of-line newline character, and file is telling you this file has none, so its single line just stops with no newline after it. That is a real property of the bytes, spotted without you opening the file. If you also counted this file's lines with wc -l, it would report 0 for the very same reason: no newline to count. One fact, two tools that agree.
So far every verdict has been some flavor of text. But plenty of files are not text: images, compiled programs, archives. When file reads the bytes and finds no known signature and characters that are not readable text, it gives the plainest verdict of all: data. That single word means "raw bytes, not human-readable text."
The binaries room holds payload.bin, a small file of raw bytes. Ask file what it is:
file ~/intercept/binaries/payload.bin
prompt: student@linuxcamp:~$ answer: file ~/intercept/binaries/payload.bin output: /home/student/intercept/binaries/payload.bin: data hint: Type file, a space, then the payload path: file ~/intercept/binaries/payload.bin
One word: data. file read payload.bin and found bytes that are not readable text and match no known file signature, so it refused to guess further and simply called it data. This is exactly the verdict that should stop you from running cat on it. data means "do not expect to read this with your eyes"; reach for a byte viewer instead. The category data is rock-solid: it means the same thing on every machine.
file does not only judge ordinary files. On Linux a folder is called a directory, and a directory is itself a kind of thing on disk. Point file at one and it names it for what it is, rather than trying to read text out of it.
Aim file at the binaries folder itself, not a file inside it:
file ~/intercept/binaries
prompt: student@linuxcamp:~$ answer: file ~/intercept/binaries output: /home/student/intercept/binaries: directory hint: Give file the folder path with no file name on the end: file ~/intercept/binaries
The verdict is directory. file recognized that this path is a folder, not a file with contents to sniff, and said so plainly. Now you have met the three verdicts you will see most: text (in its various forms), data for raw bytes, and directory for a folder. Whatever you point file at, it lands in one of these families.
You rarely inspect just one file. file takes as many paths as you want to list, separated by spaces, and reports on each in turn. When you pass more than one, it lines the verdicts up in a neat column so they are easy to scan.
Here is what that looks like across three very different files, a text note, a data blob, and a curious four-byte file called magic.bin:
/home/student/intercept/intel/notes.md: ASCII text, with no line terminators
/home/student/intercept/binaries/payload.bin: data
/home/student/intercept/binaries/magic.bin: text
The colons do not line up, but the verdicts do: file pads each line so the type column starts at the same spot. One command, three answers, and again not one of them looked at the extension.
That third file, magic.bin, is a deliberate trick. Its four bytes happen to fall in a range some versions of file read as printable characters, so different machines may label it text, name a specific text encoding, or even call it data. That is the one honest caveat about file: the broad category (text vs data vs directory) is dependable everywhere, but the exact fine-grained wording can shift between machines and file versions. Trust the family, not the last adjective. For a verdict you can rely on, payload.bin is unambiguously data on every machine.
By default file prints the path first, then the verdict. Sometimes you want only the verdict, with no path in front, for example when you are feeding the answer into another tool or you already know which file you asked about. The -b flag does that. -b is short for brief: same identification, just the type by itself.
Run the brief form on the data file:
file -b ~/intercept/binaries/payload.bin
prompt: student@linuxcamp:~$ answer: file -b ~/intercept/binaries/payload.bin output: data hint: Put -b between file and the path: file -b ~/intercept/binaries/payload.bin
Just data, with the path stripped off the front. -b did not change how file decided the type; it only trimmed the output down to the answer itself. That is the whole flag: same verdict, no path label. It is handy the moment you want the type on its own, clean enough to hand to another command.
The plain verdict, ASCII text or data, is written for a human to read. Programs prefer a stricter, standardized label called a MIME type: a short two-part code like text/plain or image/png that software everywhere agrees on. file can print that form instead of the friendly sentence, with the -i flag.
Ask for the MIME type of the log:
file -i ~/intercept/logs/messages.log
prompt: student@linuxcamp:~$ answer: file -i ~/intercept/logs/messages.log output: /home/student/intercept/logs/messages.log: text/plain; charset=us-ascii hint: Put -i between file and the path: file -i ~/intercept/logs/messages.log
Same file, same judgment, different vocabulary. Instead of ASCII text you got text/plain; charset=us-ascii. The text/plain is the MIME type, the standardized code that programs use to decide how to handle a file. The charset=us-ascii part names the character set it found. Run -i on payload.bin instead and you would get application/octet-stream, the MIME way of saying "generic raw bytes," the same idea the plain form calls data. Use the everyday form for yourself, -i when a program needs the answer.
Scaffolding off. No command is shown this time. You have every piece you need.
A file has landed in the binaries room named payload.bin. The name and the .bin extension tell you nothing you can trust. Use the one command from this lesson to make it confess what it truly is, path and verdict, plain form, no flags.
prompt: student@linuxcamp:~$ answer: file ~/intercept/binaries/payload.bin output: /home/student/intercept/binaries/payload.bin: data hint: The command is file, followed by the path to the file. No flags needed: file ~/intercept/binaries/payload.bin
The mystery file confessed: data, raw bytes and not text, judged by its contents with the extension ignored. You picked file from memory, pointed it at the path, and read the true type. That is exactly the move the real machine will ask of you when a strange file shows up and you need to know what you are dealing with before you touch it.
You earned this cheat sheet. Every row is a form of file you just ran:
The one idea to carry away: file reads what is actually inside a file and tells you its true type, no matter what the name claims. The broad category, text or data or directory, is dependable on any machine; the fine wording can vary. It is the command you run first on anything unfamiliar, so you know what you are holding before you open it.
Pair file with the readers you already know. When file says text, open it with cat, head, or less. When file says data, do not cat it; those bytes are for a viewer, not your eyes. Let file pick the tool for you.
The practice terminal has shown you every form of file: the plain verdict, several files at once, the brief -b, and the MIME-type -i. The Reading Files module ends with one real Linux machine, and that is where you identify files for real.
In the reading-files capstone mission, a live VM boots just for you on this same intercept filesystem, with the same logs, intel, and binaries rooms. Its objectives use exactly what you practiced here: file to tell text from data from a directory, -b for the bare verdict, and -i for the MIME type. There you will also meet the sibling readers this module teaches in their own lessons, cat, head, tail, wc, and the byte viewers, but identifying a file's type is the file command's job alone. One difference from here: the mission shows no commands. You read the objective, recall the flag, and type it. That recall is what makes it stick.
Finish the other Reading Files lessons, then go identify the station's files for real.
Practice file in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.