Viewing Files with cat, less, head, and tail
DevOps engineers constantly inspect configuration files, build output, service logs, generated reports, and command streams. This lesson develops a deliberate tool-selection model so you can view the right amount of text without flooding the terminal or hiding important context.
Learning objectives
By the end of this lesson
- Explain the difference between writing an entire file, paging interactively, and selecting a bounded region.
- Use
cat,less,head, andtailwith explicit options and safe filenames. - Follow a growing log while recognizing rotation, truncation, and termination behavior.
- Choose viewing commands according to file size, format, and operational purpose.
- Create and inspect a small deployment-log laboratory without elevated privileges.
1. Viewing text is a stream operation
Linux text tools generally read bytes from one or more input files—or from standard input—and write selected output to standard output. They do not “open” a file in the graphical sense. This stream model lets the same command work with a pathname, a pipe, redirected input, or generated data.
flowchart LR Q["What must you learn?"] --> A["Entire small file"] Q --> B["Interactive exploration"] Q --> C["First records"] Q --> D["Latest or changing records"] A --> CAT["cat"] B --> LESS["less"] C --> HEAD["head"] D --> TAIL["tail or tail -F"]
Do not print a multi-gigabyte log merely because cat can read it. Select the minimum output that answers the current question, then expand the investigation when necessary.
2. Use cat for complete, bounded output
cat concatenates files and writes them in order. It is ideal for a short configuration file, a generated fragment, or joining several known inputs. It is not an interactive viewer and it does not protect the terminal from huge, binary, or sensitive content.
lab="$HOME/devops-academy/linux/chapter05/lesson01"
mkdir -p -- "$lab"
printf '%s\n' \
'service=orders-api' \
'environment=staging' \
'replicas=3' > "$lab/deployment.conf"
cat -- "$lab/deployment.conf"
# Concatenate known files with visible boundaries.
for file in "$lab"/*.conf; do
printf '\n=== %s ===\n' "$file"
cat -- "$file"
doneThe -- separator prevents a filename beginning with a dash from being parsed as an option. Options such as -n can number all output lines, but numbering is often clearer with the dedicated nl utility when formatting matters.
Before printing an unfamiliar file, inspect it with file, stat, or a bounded hexadecimal tool. Terminal control bytes can make output unreadable, and configuration files may contain credentials or tokens.
3. Explore large text interactively with less
less displays one screen at a time and normally avoids reading the entire file before it starts. This makes it suitable for long logs, manuals, and reports. The viewer runs in the foreground until you quit.
Space / bForward or backward one screenSurvey nearby context/patternSearch forwardFind an error, request ID, or timestampn / NNext or previous matchMove among occurrencesg / GFirst or last lineJump to start or recent outputFFollow growing inputWatch appended log recordsqQuitReturn to the shell# Page through a file and preserve long lines for horizontal inspection.
less -S -- "$lab/deployment.log"
# Show line numbers and start at the first ERROR occurrence.
less -N +/ERROR -- "$lab/deployment.log"
# Page the output of another command.
systemctl --no-pager status ssh 2>/dev/null | lessEnvironment variables such as LESS can define personal defaults, but automation should not depend on an operator’s pager configuration. Commands used in scripts should generally disable pagers or direct output explicitly.
4. Select the beginning or end with head and tail
head outputs the first ten lines by default; tail outputs the last ten. Use -n for a line count and -c for a byte count. Explicit counts make intent visible.
# First five records.
head -n 5 -- "$lab/deployment.log"
# Everything except the final two records (GNU syntax).
head -n -2 -- "$lab/deployment.log"
# Last twenty records.
tail -n 20 -- "$lab/deployment.log"
# Start at record 11 and continue to the end.
tail -n +11 -- "$lab/deployment.log"Positive +N syntax means “start with item N,” while a conventional count means “take this many from the end or beginning.” Some negative-count forms are GNU extensions, so portable scripts should verify their target environment.
Following a changing log
# Follow the currently open file descriptor.
tail -f -- "$lab/deployment.log"
# Follow by name and retry when a rotated file is recreated.
tail -F -- "$lab/deployment.log"
# Stop automatically after 30 seconds.
timeout 30s tail -F -- "$lab/deployment.log"tail -f is useful when the same file remains open and grows. GNU tail -F follows by name and retries, which is often more resilient when log rotation renames the old file and creates a new one. Always know how the follow operation will terminate: normally Ctrl+C, a timeout, or a monitored process ID.
5. Match the command to the question
cat
Use when every line is needed and output volume is predictably bounded.
less
Use for navigation, search, context, and horizontal scrolling.
head
Use to inspect schemas, banners, or the first records of generated output.
tail
Use for latest events, bounded history, and controlled following.
These commands compose naturally with filters. For example, a later lesson will use grep to select matching lines before paging them with less. The order matters because each stage changes what the next stage receives.
6. Hands-on lab: inspect a synthetic deployment log
Create a repeatable log, answer bounded questions, and observe a follow session. The lab stays entirely under your home directory.
lab="$HOME/devops-academy/linux/chapter05/lesson01"
mkdir -p -- "$lab"
log="$lab/deployment.log"
: > "$log"
for minute in $(seq 1 30); do
level=INFO
message="health check passed"
if (( minute == 7 || minute == 19 )); then
level=ERROR
message="upstream timeout"
elif (( minute % 10 == 0 )); then
level=WARN
message="latency threshold exceeded"
fi
printf '2026-08-04T09:%02d:00Z level=%s service=orders-api message="%s"\n' \
"$minute" "$level" "$message" >> "$log"
done
printf '%s\n' '=== first three records ==='
head -n 3 -- "$log"
printf '%s\n' '=== latest five records ==='
tail -n 5 -- "$log"
printf '%s\n' '=== total records ==='
wc -l < "$log"
# In another terminal, run: tail -F -- "$log"
printf '%s\n' '2026-08-04T09:31:00Z level=INFO service=orders-api message="deployment complete"' >> "$log"Verification checklist
7. Common mistakes and stronger habits
Printing an unknown large file
Inspect size and type first, then use head or less instead of unbounded output.
Using tail -f without a termination plan
Interactive sessions need a known interrupt; automation needs a timeout or process-based exit condition.
Assuming the final lines contain the cause
The error may have earlier context. Search by request ID, timestamp, or component and widen the surrounding window.
Depending on a pager in scripts
Pagers are interactive. Disable them or redirect deterministic output when automation must not block.
8. Knowledge check
Question 1. Why is less usually safer than cat for an unfamiliar large log?
Question 2. What operational difference commonly separates tail -f from GNU tail -F?
-f follows the open file, while -F follows by name and retries, making it more resilient to typical rename-and-recreate log rotation.Question 3. What does tail -n +11 request?
9. Summary
cat writes complete bounded inputs, less supports interactive exploration, head selects the beginning, and tail selects or follows the end. Strong operations begin by identifying the question and choosing the smallest view that can answer it.
10. Further reading
- GNU Coreutils manual —
cat,head,tail, andwc. lessmanual page and built-in help.- GNU Bash Reference Manual — pipelines, redirection, quoting, and job control.
- systemd documentation — journal output and pager controls.
- Linux manual pages for
file,stat, andtimeout.
Keep the academy open
Support free, practical DevOps education.
Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this address.