Follow a log and see only errors
--line-buffered makes grep print matches right away instead of in batches.
The tail command prints the end of a file, and with -f it keeps showing new lines as they are appended to a log.
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
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.
systemd logs live in journald, not in files: their tail -f is journalctl -f (see
journalctl).
-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.
--line-buffered makes grep print matches right away instead of in batches.
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.
System logs are readable by root and the adm group. Use sudo tail, or check your
groups: id shows whether you're in adm.
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.
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.
Click the terminal so it has focus and press Ctrl+C again: without focus the browser gets the keystroke.
Found an inaccuracy? Report an error in the article