Skip to main content

Linux command: cat

06 July 2026

Almost everyone who uses Linux reaches for cat within the first hour. You type it to read a config file, to peek at a log, or to dump a short script to the screen. It feels like "the command that prints a file". That is true, but it is not the whole story, and it is not even what the name means. The real job of cat is to join files together, and once you see that, a lot of Unix suddenly fits into place.

1. The Basics

The job of cat is to concatenate one or more files and send the result to standard output, which is usually your terminal. When you give it a single file, it prints that file. When you give it several files, it prints them one after another, glued end to end. Printing one file is just the simplest case of joining files: a list of one.

Two ideas make cat special. First, it writes to standard output, not to a fixed place. That means its result can go to your screen, into another command through a pipe, or into a new file through a redirect. cat does not care where the output ends up; the shell decides that. Second, cat is a tiny, honest tool that does exactly one thing. It does not page, it does not wrap, it does not stop at the bottom of the screen. That simplicity is a feature, and knowing its limits is part of using it well.

The command everyone thinks of as "print a file". Behind those three letters sits its real purpose, concatenation, and a clean lesson in how Unix commands read input and write output.

This article starts with the simplest possible use and builds up to redirection, here-documents, reading from standard input, and the famous "useless use of cat". By the end you will know not only how to print a file, but when cat is the wrong tool and which command takes over.

The right mental model: cat is a pipe with a name. It reads its inputs in order, joins them into one stream, and pours that stream into standard output. Everything else is just where that stream is pointed.

Back to top

2. Where the Name Comes From

The name cat is short for concatenate, which means "to link together in a series". It has nothing to do with the animal.

cat  =  conCATenate

The name tells you the original purpose exactly. In early Unix, if you wanted to join three files into one, you ran cat part1 part2 part3 and captured the combined output. Printing a single file to the screen was a happy side effect: joining one file and letting the result fall onto the terminal.

Like most early Unix commands, the name was kept short on purpose. Early Unix was typed on slow teletype terminals that printed each character onto paper, so short names saved both time and ink. That is why cat is three letters and not "concatenate".

Back to top

3. A Short History

The cat command is one of the oldest Unix tools still in daily use. It shipped in Unix 1st Edition at Bell Labs in 1971 and has been present on every Unix-like system since: Linux, macOS, the BSDs, Solaris, and AIX. It replaced a pair of older, more specialised commands for copying and printing files, folding their jobs into one small program.

EraMilestone
1971 cat ships in Unix 1st Edition at Bell Labs
1970s-80s Becomes a building block of the Unix "pipes and filters" style
1980s BSD adds flags such as -v to reveal non-printing characters
Today The GNU coreutils cat runs on most Linux distributions

There are two versions you will meet in practice. Most Linux systems run the GNU coreutils version of cat. macOS and the BSDs ship the BSD version. They agree on the core behaviour and on the short flags such as -n, -b, and -s. The main difference is that GNU adds long options (for example --number) and the combined -A flag, which BSD does not have. This article uses the GNU version, which is what you will find on almost every Linux server.

A command over fifty years old, still typed every day and unchanged in spirit, is proof that a tool which does one thing well never goes out of date.

Back to top

4. Simple Use Cases

4.1 The Simplest Possible Use

Give cat a filename and it prints that file to the screen. In the examples below, the line that starts with $ is what you type, and the lines under it are what the system prints back.

$ cat notes.txt
Buy milk
Call the dentist
Finish the report

The whole file is sent to the terminal at once. This is ideal for short files: a config file, a small script, a note. For long files it is the wrong tool, and section 7 explains why.

4.2 Joining Several Files: The Original Job

Give cat more than one file and it prints them in order, one after another, with no separator between them. This is the concatenation the name promises:

$ cat chapter1.txt chapter2.txt chapter3.txt
(the full text of chapter 1)
(the full text of chapter 2)
(the full text of chapter 3)

On its own this just floods the screen. It becomes useful the moment you send the combined stream somewhere, which brings us to redirection.

4.3 Saving the Result to a New File

The shell operator > redirects standard output into a file instead of the screen. Combine it with cat to actually join files into a new one:

$ cat chapter1.txt chapter2.txt chapter3.txt > book.txt

Now book.txt contains the three chapters, in order, as one file. This single line is the reason cat exists. Note that the joining is done by cat, but the saving is done by the shell's >, not by cat itself.

A useful distinction: cat produces a stream, the shell decides where the stream goes. > writes it to a new file, >> appends it to an existing one, and a pipe | hands it to the next command.

4.4 Reading From the Keyboard

Run cat with no filename at all and it reads from standard input, which by default is your keyboard. It echoes back each line you type until you press Ctrl-D, the key that signals "end of input":

$ cat
hello
hello
this is a test
this is a test
[Ctrl-D]

Combine that with a redirect and you have the classic quick way to create a short file without opening an editor:

$ cat > shopping.txt
milk
eggs
bread
[Ctrl-D]
$ cat shopping.txt
milk
eggs
bread

You type the lines, press Ctrl-D, and the text lands in shopping.txt. It is not an editor, so you cannot go back and fix a line above, but for three lines it is faster than anything else.

Back to top

5. Moderate Use Cases

5.1 Numbering Lines: -n and -b

The -n flag (short for number) puts a line number in front of every line. This is handy when someone refers to "the error on line 42":

$ cat -n config.ini
     1	[database]
     2	host = localhost
     3	port = 5432

The related -b flag (short for number nonblank) numbers only the lines that contain text, skipping empty lines. It is nicer for reading prose or code with blank lines between blocks:

$ cat -b poem.txt
     1	Roses are red

     2	Violets are blue

5.2 Squeezing Blank Lines: -s

The -s flag (short for squeeze-blank) collapses runs of several empty lines into a single blank line. It is useful for files that have large vertical gaps:

$ cat -s spaced-out.txt      # many blank lines become one

5.3 Seeing the Invisible: -E, -T, and -A

Some of the hardest bugs come from characters you cannot see: a trailing space, a tab where you expected spaces, or Windows line endings. cat can make these visible.

FlagShort forWhat it shows
-E show-ends A $ at the end of every line
-T show-tabs Tabs as ^I instead of whitespace
-v show-nonprinting Other control characters in ^ and M- notation
-A show-all All of the above at once (equal to -vET)

Watch what -A reveals in a file that looks perfectly normal on screen:

$ cat -A messy.txt
name:^Ipeter $
city:^Iutrecht$

Now you can see that the gap after the colon is a tab (^I) and that the first line has a hidden trailing space before the $. This is the fastest way to answer "why does this line not match?" when a script misbehaves.

Back to top

6. Advanced Use Cases

6.1 Appending and Building Files

With >> you add to the end of a file instead of overwriting it. This lets you assemble a file piece by piece:

$ cat header.txt > page.html      # start fresh (overwrites)
$ cat body.txt >> page.html       # add to the end
$ cat footer.txt >> page.html     # add to the end again

Be careful with the single >: it truncates the target to empty before writing. A common and painful mistake is cat a.txt > a.txt, which empties the file before cat ever reads it. To combine a file with others in place, write to a new name first.

6.2 The Dash: Mixing Files and Standard Input

A single dash - stands for standard input in the file list, so you can splice piped data between real files. This example puts a header, then whatever another command sends, then a footer:

$ echo "=== start ===" | cat header.txt - footer.txt

Here cat prints header.txt, then the text arriving on standard input (the line from echo), then footer.txt. The dash is a small feature that turns cat into a flexible stream-joiner.

6.3 Here-Documents: A Better Way to Write a Block

The keyboard-and-Ctrl-D trick from section 4 has a cleaner cousin called a here-document. You give the shell a marker word, and everything up to that word becomes the input. This is the professional way to write a block of text into a file, especially inside scripts:

$ cat > config.yml <<EOF
server: web01
port: 8080
debug: false
EOF

Everything between <<EOF and the closing EOF is fed to cat, which writes it to config.yml. The marker can be any word; EOF is just the common convention. If you quote the marker as <<'EOF', the shell leaves $variables untouched instead of expanding them, which matters when the block contains dollar signs.

6.4 cat as a Building Block in Pipes

Because cat just prints text, it feeds naturally into the rest of the Unix toolbox through a pipe:

$ cat access.log | wc -l           # count the lines
$ cat *.txt | sort | uniq          # merge, sort, remove duplicates
$ cat notes.md | grep TODO         # find matching lines

The middle example is where cat genuinely shines: joining many files (*.txt) into a single stream before handing it to sort. That is real concatenation doing real work. The first and last examples, however, are a trap that section 7 explains.

6.5 tac: cat Backwards

GNU ships a companion called tac, which is cat spelled backwards and does exactly that: it prints a file with its lines in reverse order, last line first.

$ tac notes.txt
Finish the report
Call the dentist
Buy milk

It is genuinely useful for logs, where the newest entries sit at the bottom. tac error.log | head shows you the most recent lines first.

Back to top

7. Something Most Users Do Not Know

7.1 The "Useless Use of Cat"

Here is the habit that marks a beginner, and the fix that marks someone who understands Unix. Many people write:

$ cat file.txt | grep error       # works, but wasteful

This starts cat just to feed grep through a pipe. But grep, like almost every Unix filter, can read a file directly. The cat and the pipe add nothing:

$ grep error file.txt             # does the same, one process

This anti-pattern is so common that Randal Schwartz began handing out a tongue-in-cheek "Useless Use of Cat Award" for it on Usenet in the 1990s. The rule of thumb: if a command right after cat | can take a filename itself, drop the cat and give the file to that command. Reserve cat for when you genuinely join several files, or when you truly have nothing else to read the input.

Use cat to join files, not to feed a single file into another command. One file plus a pipe is almost always one command too many.

7.2 cat Is Not a Pager

When you run cat on a large file, it dumps the entire thing to the terminal as fast as it can. The screen scrolls past in a blur and you are left staring at the last page, unable to scroll back beyond the terminal's buffer. cat has no idea how tall your screen is; that is not its job.

For anything longer than a screen, use a pager, which shows one page at a time and lets you scroll and search:

$ less big.log        # scroll with arrows, search with /, quit with q
$ head big.log        # just the first 10 lines
$ tail big.log        # just the last 10 lines
$ tail -f big.log     # follow a log as it grows

7.3 cat on a Binary File Can Break Your Terminal

A classic surprise: run cat on a non-text file, such as a program or an image, and your prompt may turn into garbage afterwards. The file contains control bytes, and some of them are escape sequences that reconfigure the terminal, for example switching it into a graphics character set.

$ cat /bin/ls         # do not do this; the terminal may go strange

If it happens, type reset and press Enter, even if you cannot read what you are typing. That restores the terminal to a sane state. To inspect a binary safely, use a tool made for it, such as xxd, hexdump, or strings. Note that cat -v also makes the control characters visible instead of acting on them.

7.4 Under the Hood: Bytes and the Three Streams

Underneath, cat is almost the simplest program that can exist. For each file it runs a tiny loop of system calls: open() the file, read() a block of bytes, write() those bytes to standard output, and repeat until end-of-file, then close(). It never looks at what the bytes mean. Plain text, an image, or a compiled program are all the same to cat: a stream of bytes to copy through untouched.

Because it does not interpret anything, cat reproduces a file exactly. cat photo.jpg > copy.jpg makes a byte-for-byte identical file. It works, but for real copying prefer cp, which also preserves permissions and timestamps and can use faster kernel copy paths.

This is also the clearest place to meet the three standard streams that every Unix process is born with. Each one has a number, called a file descriptor:

StreamNumberDefault
standard input (stdin) 0 The keyboard
standard output (stdout) 1 The terminal
standard error (stderr) 2 The terminal, kept separate on purpose

Everything in section 4 is just these streams being pointed somewhere. cat reads from stdin (0) when you give no filename, writes its result to stdout (1) always, and sends errors such as "No such file" to stderr (2), so a bad filename does not silently pollute the file you are building. Those descriptor numbers are also why you will later meet 2>&1, which means "send stream 2 to wherever stream 1 is going".

7.5 Knowing Where cat Stops

Part of expertise is knowing when a tool is the wrong one. cat reads and joins; the moment you want to view, search, or select, another command does it better:

NeedUseWhy
Read a long file less Pages, scrolls, and searches instead of flooding the screen
Just the start or end head / tail Shows the first or last lines without the rest
Find matching lines grep Reads the file directly, no cat needed
Save and see a stream at once tee Writes to a file and to the screen in one pass
Inspect a binary xxd / strings Shows bytes safely instead of corrupting the terminal

Learn cat first anyway. It is installed on every machine you will ever log in to, including a bare container or a rescue shell, and it is the clearest illustration of how Unix commands read input and write output.

Back to top

8. Best Practices

  • Use cat for what it is named after. Reach for it when you join several files. For a single file feeding another command, give that command the filename directly.
  • Do not cat a large file. Use less to read it, or head and tail for the ends. Save your terminal buffer and your patience.
  • Never redirect a file onto itself. cat a > a empties the file. Write to a new name, then rename it if needed.
  • Reveal hidden characters when a match fails. When a script does not behave, run cat -A to expose tabs, trailing spaces, and stray line endings.
  • Reach for the manual without hesitation. The habit that separates beginners from professionals is not memorising every flag; it is typing man cat the moment a question comes up.
$ man cat                            # the full manual page
$ cat --help                         # a quick flag summary (GNU)
$ info coreutils 'cat invocation'    # the verbose GNU manual
Back to top

9. Common Mistakes

9.1 Three Common Myths

MythReality
"cat means print a file." It means concatenate. Printing one file is just joining a list of one.
"cat file | grep x is normal." It is a useless use of cat. Write grep x file instead.
"cat is the way to read any file." For anything longer than a screen, less is the right tool.

9.2 Other Traps to Avoid

  • Overwriting with a single >. cat x > out replaces out completely. Use >> when you mean to append.
  • Reading into the same file. cat a b > a destroys a before it is read. Always redirect to a fresh filename.
  • cat-ing a binary. It can scramble your terminal. Run reset to recover, and use xxd or strings to inspect binaries.
  • Expecting a separator between files. cat a b glues the files with nothing in between. If a does not end in a newline, its last line runs straight into b.
  • Using cat to count or search. Tools like wc and grep take a filename themselves. The extra cat only adds a process.
Back to top

10. Summary

The cat command looks trivial, but it is a clean lesson in how Unix reads input and writes output.

  • cat means "concatenate". Its real job is to join files and send the result to standard output; printing one file is the simple case.
  • It dates back to Unix in 1971 and runs, unchanged in spirit, on every Unix-like system today.
  • cat a b c > out joins files into a new one. > overwrites, >> appends, and a pipe | hands the stream to the next command.
  • With no filename, cat reads the keyboard until Ctrl-D. A here-document (<<EOF) is the cleaner way to write a block of text.
  • Useful flags: -n and -b number lines, -s squeezes blank lines, and -A reveals tabs, line ends, and hidden characters.
  • The dash - means standard input, so you can splice piped data between real files. tac prints a file in reverse.
  • Avoid the "useless use of cat": if the next command can read a file itself, skip cat and the pipe.
  • Under the hood, cat is a small loop of read() and write() over the three standard streams: stdin (0), stdout (1), and stderr (2). It copies bytes without interpreting them.
  • Know where cat stops: less to read long files, head and tail for the ends, grep to search, tee to save and display at once, and xxd or strings for binaries.
  • When in doubt, type man cat.

This is the quick reference worth keeping:

cat file             print one file
cat a b c            join files, in order, to the screen
cat a b c > out      join files into a new file
cat f1 >> f2         append f1 to the end of f2
cat > file           type text, end with Ctrl-D
cat -n file          print with line numbers
cat -A file          reveal tabs, line ends, and control chars
cat -s file          collapse repeated blank lines
grep x file          NOT cat file | grep x
less file            read a long file the right way
tee file             save a stream to a file AND the screen
tac file             print a file in reverse
Back to top
Linux command: cat
Peter Martin
Peter Martin
Joomla Specialist

Peter is a Joomla specialist and a Linux admin for fast, secure and scalable websites.