Where to start First steps track · 15 stages
Linux Labs

tail — the last lines and following a log

5 min Ubuntu 24.04 · GNU coreutils 9.4

The tail command prints the end of a file, and with -f it keeps showing new lines as they are appended to a log.

Cheat sheet

8 commands Printable version
  • tail app.log the last 10 lines
  • tail -n 50 app.log the last 50 lines
  • tail -n +2 data.csv everything from line 2 on
  • tail -f /var/log/nginx/error.log follow; Ctrl+C to quit
  • tail -F app.log follow and survive log rotation
  • tail -n 0 -f app.log only new lines, no old ones
  • tail -f a.log b.log two files at once, with names
  • tail -f app.log | grep --line-buffered ERROR follow errors only

Overview

tail prints the end of a file: 10 lines with no options, N lines with -n N. New log entries are appended at the end, so tail is the first look at "what just happened".

-f (follow) doesn't exit: tail waits and prints every line appended to the file. That's how you watch a service's log while reproducing an error in another window. Quit with Ctrl+C.

text
student@ubuntu:~$ tail -n 3 /var/log/dpkg.log
2026-10-18 09:12:41 status installed tree:amd64 2.1.1-2ubuntu3
2026-10-18 09:12:41 trigproc man-db:amd64 2.12.0-4build2 <none>
2026-10-18 09:12:42 status installed man-db:amd64 2.12.0-4build2

systemd logs live in journald, not in files: their tail -f is journalctl -f (see journalctl).

Options

6

-n 50 and the short form -50 are the same. The +N in -n +N means "starting at line N". Full list — man tail.

Option What it does Example
-n N Print the last N lines; -n +N starts at line N. tail -n 50 app.log
-f Keep running and print lines as they are appended. tail -f /var/log/nginx/error.log
-F Like -f, but follow by name and reopen the file after rotation. tail -F app.log
-c N Print the last N bytes. tail -c 200 app.log
--pid PID With -f, exit when process PID ends. tail -f build.log --pid=4242
-q Never print ==> name <== headers for several files. tail -q -n 1 *.log

Nothing found. Try a shorter query.

Recipes

4

Follow a log and see only errors

bash
tail -F /var/log/nginx/error.log | grep --line-buffered -i error

--line-buffered makes grep print matches right away instead of in batches.

Skip the header line

bash
tail -n +2 report.csv | sort -t, -k3 -n   # data without the header

The last lines of several logs at once

text
student@ubuntu:~$ tail -n 1 /var/log/dpkg.log /var/log/apt/history.log
==> /var/log/dpkg.log <==
2026-10-18 09:12:42 status installed man-db:amd64 2.12.0-4build2

==> /var/log/apt/history.log <==
End-Date: 2026-10-18  09:12:42

Stop following when a process ends

bash
tail -f build.log --pid=$(pgrep -n make)   # exits when make finishes

Troubleshooting

5

tail -f went quiet after log rotation

logrotate renamed the file and created a new one, while tail -f keeps reading the old one. Follow by name: tail -F reopens the file when it's replaced.

tail: cannot open: Permission denied

System logs are readable by root and the adm group. Use sudo tail, or check your groups: id shows whether you're in adm.

tail: cannot open 'x' for reading: No such file or directory

The file doesn't exist — maybe the service logs to journald instead of a file. Check ls /var/log/ and journalctl -u service -n 50.

New lines show up late

The program buffers its output, not tail. In a pipeline after tail -f, add --line-buffered to grep, or put stdbuf -oL before the command.

Ctrl+C doesn't bring the prompt back

Click the terminal so it has focus and press Ctrl+C again: without focus the browser gets the keystroke.

See also

  • head — the start of a file.
  • less — page and search; F in less works like tail -f.
  • journalctl — systemd logs, journalctl -f.
  • logrotate — why log files get renamed.
  • grep — pick the lines you need from a stream.
  • cat — the whole file.
Loading…