Chapter 05Lesson 01~50 minutes

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.

BeginnerText inspectionHands-on lab

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, and tail with 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.

Choose the smallest useful view
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"]
Operational principle

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"
done

The -- 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.

Binary and secret data

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.

KeyActionOperational use
Space / bForward or backward one screenSurvey nearby context
/patternSearch forwardFind an error, request ID, or timestamp
n / NNext or previous matchMove among occurrences
g / GFirst or last lineJump to start or recent output
FFollow growing inputWatch appended log records
qQuitReturn 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 | less

Environment 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

Small and complete

cat

Use when every line is needed and output volume is predictably bounded.

Large and exploratory

less

Use for navigation, search, context, and horizontal scrolling.

Headers or samples

head

Use to inspect schemas, banners, or the first records of generated output.

Recent or live

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?

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.

Next lesson

Searching Text with grep and Regular Expressions

The next lesson turns file viewing into precise pattern selection and automation-friendly search.

10. Further reading

  • GNU Coreutils manual — cat, head, tail, and wc.
  • less manual 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, and timeout.

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.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.