7 Linux Tail Command Examples and How it Helps Monitor Logs

linux tail commandAs you may know, cat command is used in displaying the entire content of a file via standard input. But in some cases, we have to print part of the file. The Linux tail command works in a similar way like the cat command. It displays the last 10 lines of a file using standard output. It is also used to follow a file and watch as new lines are being added to it. This is mostly used for viewing log file updates as these updates are appended to the log files. This article explains tail command with it’s most common options.

The tail command accepts input from STDIN. By default, the tail command displays last ten lines. So at STDIN, if you enter more than 10 lines, only last 10 lines will be displayed. The head command does the exact opposite of the tail command.

In the following example, I will input numbers in descending order from 12 and after inputting 1, I will press CTRL+ D (i.e. end of file marker)

$ tail
12
11
10
9
8
7
6
5
4
3
2
1
10
9
8
7
6
5
4
3
2
1

1) Viewing the last ten lines of a file

With a filename as the argument, it displays last 10 lines for that file.

$ tail file1.txt
memtest86+_multiboot.bin
System.map-2.6.38-12-generic
System.map-2.6.38-13-generic
System.map-2.6.38-8-generic
vmcoreinfo-2.6.38-12-generic
vmcoreinfo-2.6.38-13-generic
vmcoreinfo-2.6.38-8-generic
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
vmlinuz-2.6.38-8-generic

2) Showing multiple files

If multiple files are given as argument, it outputs the last 10 lines of each file and precedes each with a header displaying the name of the file.

$ tail file1.txt file2.txt
==> file1.txt <== memtest86+_multiboot.bin System.map-2.6.38-12-generic System.map-2.6.38-13-generic System.map-2.6.38-8-generic vmcoreinfo-2.6.38-12-generic vmcoreinfo-2.6.38-13-generic vmcoreinfo-2.6.38-8-generic vmlinuz-2.6.38-12-generic vmlinuz-2.6.38-13-generic vmlinuz-2.6.38-8-generic 
==> file2.txt <== smi.conf snmp sound speech-dispatcher ssh ssl sudoers sudoers.d sysctl.conf sysctl.d

If you do not want to print the headers, you can use quiet mode with -q, --quiet or --silent option. This option can be used to combine files.

$ tail -q file1.txt file2.txt
memtest86+_multiboot.bin
System.map-2.6.38-12-generic
System.map-2.6.38-13-generic
System.map-2.6.38-8-generic
vmcoreinfo-2.6.38-12-generic
vmcoreinfo-2.6.38-13-generic
vmcoreinfo-2.6.38-8-generic
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
vmlinuz-2.6.38-8-generic
smi.conf
snmp
sound
speech-dispatcher
ssh
ssl
sudoers
sudoers.d
sysctl.conf
sysctl.d

If you always want to print headers, even when only one filename is provided as argument, you can use -v or --verbose option

$ tail -v file1.txt
==> file1.txt <== memtest86+_multiboot.bin System.map-2.6.38-12-generic System.map-2.6.38-13-generic System.map-2.6.38-8-generic vmcoreinfo-2.6.38-12-generic vmcoreinfo-2.6.38-13-generic vmcoreinfo-2.6.38-8-generic vmlinuz-2.6.38-12-generic vmlinuz-2.6.38-13-generic vmlinuz-2.6.38-8-generic

3) Displaying different number of lines

When you want to change the default behavior and change the last number of lines from 10 to something else, -n option is used

$ tail -n3 file1.txt
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
Vmlinuz-2.6.38-8-generic

You can also use -3 directly to print last the 3 lines

$ tail -3 file1.txt
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
vmlinuz-2.6.38-8-generic

4) Printing the last K bytes of a file

For printing the last K bytes of the file, use -c or --bytes=K option. This prints last 30 bytes of the file

$ tail -c 30 file2.txt
sudoers.d
sysctl.conf
sysctl.d

Alternatively, you can use -c +K to output bytes starting with the Kth of each file.

$ tail -c +300 file1.txt
config-2.6.38-8-generic
grub
initrd.img-2.6.38-12-generic
initrd.img-2.6.38-13-generic
initrd.img-2.6.38-8-generic
memtest86+.bin
memtest86+_multiboot.bin
System.map-2.6.38-12-generic
System.map-2.6.38-13-generic
System.map-2.6.38-8-generic
vmcoreinfo-2.6.38-12-generic
vmcoreinfo-2.6.38-13-generic
vmcoreinfo-2.6.38-8-generic
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
vmlinuz-2.6.38-8-generic

5) Viewing a Growing File (example log files)

When viewing a log file and you want to check the changes being made or latest additions at the end of the file, i.e. if you want to output appended data as the file grows, use -f or --follow option. This option is very commonly used for troubleshooting as it continously show logs updates on your terminal.

$ tail -f /var/log/Xorg.1.log
[ 86.774] (**) Option "xkb_layout" "us"
[ 86.774] (**) Option "xkb_options" "terminate:ctrl_alt_bksp"
[ 86.774] (II) Toshiba input device: (II) is tagged by udev as: Keyboard
[ 86.774] (II) Toshiba input device: (II) device is a keyboard
[ 88.453] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 88.453] (II) Vision stereo.
[ 102.094] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 102.094] (II) Vision stereo.
[ 540.435] (II) Axis 0x1 value 1158 is outside expected range
See https://wayland.freedesktop.org for details

The -f switch will wait for the appended data and won’t quit. Now in the other terminal, let us append a line to the file

$ echo "hello" /var/log/Xorg.1.log

It will appear on the previous terminal as

[ 86.774] (**) Option "xkb_layout" "us"
[ 86.774] (**) Option "xkb_options" "terminate:ctrl_alt_bksp"
[ 86.774] (II) Toshiba input device: (II) is tagged by udev as: Keyboard
[ 86.774] (II) Toshiba input device: (II) device is a keyboard
[ 88.453] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 88.453] (II) Vision stereo.
[ 102.094] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 102.094] (II) Vision stereo.
[ 540.435] (II) Axis 0x1 value 1158 is outside expected range
See https://wayland.freedesktop.org for details
hello

Let’s try to display the last 3 lines of a tail output using the -n and f options.

$ tail -n3 -f /var/log/Xorg.1.log
[ 102.094] (II) Vision stereo.
[ 540.435] (II) Axis 0x1 value 1158 is outside expected range
See https://wayland.freedesktop.org for details

Now in the other terminal, let us append some line in the file

$ echo "new addition" >> /var/log/Xorg.1.log

It will appear on the previous terminal as

See https://wayland.freedesktop.org for details
hello
new addition

Using the -fq switch allows you to follow multiple files with their headers removed

$ tail -fq /var/log/Xorg.1.log file2.txt
[ 86.774] (**) Option "xkb_layout" "us"
[ 86.774] (**) Option "xkb_options" "terminate:ctrl_alt_bksp"
[ 86.774] (II) Toshiba input device: (II) is tagged by udev as: Keyboard
[ 86.774] (II) Toshiba input device: (II) device is a keyboard
[ 88.453] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 88.453] (II) Vision stereo.
[ 102.094] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 102.094] (II) Vision stereo.
[ 540.435] (II) Axis 0x1 value 1158 is outside expected range
See https://wayland.freedesktop.org for details
memtest86+_multiboot.bin
System.map-2.6.38-12-generic
System.map-2.6.38-13-generic
System.map-2.6.38-8-generic
vmcoreinfo-2.6.38-12-generic
vmcoreinfo-2.6.38-13-generic
vmcoreinfo-2.6.38-8-generic
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
vmlinuz-2.6.38-8-generic

Now in the other terminal, let us append a line to both files

$ echo "linoxide" >> /var/log/Xorg.1.log
$ echo "hello world" >> file2.txt

It will appear on the previous terminal as

[ 86.774] (**) Option "xkb_layout" "us"
[ 86.774] (**) Option "xkb_options" "terminate:ctrl_alt_bksp"
[ 86.774] (II) Toshiba input device: (II) is tagged by udev as: Keyboard
[ 86.774] (II) Toshiba input device: (II) device is a keyboard
[ 88.453] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 88.453] (II) Vision stereo.
[ 102.094] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 102.094] (II) Vision stereo.
[ 540.435] (II) Axis 0x1 value 1158 is outside expected range
See https://wayland.freedesktop.org for details
linoxide
memtest86+_multiboot.bin
System.map-2.6.38-12-generic
System.map-2.6.38-13-generic
System.map-2.6.38-8-generic
vmcoreinfo-2.6.38-12-generic
vmcoreinfo-2.6.38-13-generic
vmcoreinfo-2.6.38-8-generic
vmlinuz-2.6.38-12-generic
vmlinuz-2.6.38-13-generic
vmlinuz-2.6.38-8-generic
hello world

With the -s or --sleep-interval=N (default is 1 second), you can adjust the sleep interval between the iterations. This means it will check after the provided number of seconds for the append updates.

$ tail -f -s 4 /var/log/Xorg.1.log
[ 86.774] (**) Option "xkb_layout" "us"
[ 86.774] (**) Option "xkb_options" "terminate:ctrl_alt_bksp"
[ 86.774] (II) Toshiba input device: (II) is tagged by udev as: Keyboard
[ 86.774] (II) Toshiba input device: (II) device is a keyboard
[ 88.453] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 88.453] (II) Vision stereo.
[ 102.094] (II) Display (Seiko/Epson (DFP-0)) does not support NVIDIA 3D
[ 102.094] (II) Vision stereo.
[ 540.435] (II) Axis 0x1 value 1158 is outside expected range
See https://wayland.freedesktop.org for details
Hello 
new addition 
another addition

The follow option does not exit by itself. But you can tell the command to terminate after a process dies with the --pid=PID option.

$ tail -f file2.txt --pid=4309
snmp
sound
speech-dispatcher
ssh
ssl
sudoers
sudoers.d
sysctl.conf
sysctl.d
hello

The command will exit as soon as the process with PID 4309 dies.

With the --retry option, you can keep trying to open a file even when it is, or becomes, inaccessible. Once it becomes accessible, the output will be displayed.

$ tail -f file2.txt --retry

6) Using tail with pipes

The tail command can be piped to from other commands. This example shows the sorting of a directory so all the directories are listed first.

$ ls -l /etc | tail -n +2 | sort
drwxr-xr-x 8 root root 4096 Oct 18 2016 NetworkManager
lrwxrwxrwx 1 root root 19 May 15 2016 mtab -> ../proc/self/mounts
lrwxrwxrwx 1 root root 21 Feb 7 23:55 os-release -> ../usr/lib/os-release
lrwxrwxrwx 1 root root 23 May 15 2016 vtrgb -> /etc/alternatives/vtrgb
lrwxrwxrwx 1 root root 29 May 15 2016 resolv.conf -> ../run/resolvconf/resolv.conf
lrwxrwxrwx 1 root root 32 Dec 25 14:43 localtime -> /usr/share/zoneinfo/Africa/Accra
-r--r----- 1 root root 798 Dec 5 18:12 sudoers
-r--r--r-- 1 root root 33 May 15 2016 machine-id
-rw------- 1 root root 1123 Mar 10 15:03 group-
-rw------- 1 root root 1385 Jan 26 16:33 shadow-
-rw------- 1 root root 196 Jun 12 2016 ddclient.conf

The command below reads last 13 lines of "default" file cuts out the # comment symbols, and outputs the result to a new file called "sample.com"

$tail /etc/nginx/sites-available/default -n 13 | cut -c 2- | sudo tee /etc/nginx/sites-available/sample.com 1> /dev/null

7) Checking the Linux tail command version

The --version option is used to display the version of tail which is currently on your system.

$ tail --version
tail (GNU coreutils) 8.13
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by Paul Rubin, David MacKenzie, Ian Lance Taylor,
and Jim Meyering.

Conclusion

Now we've seen how to use the tail commands and it's switches to display the bottom lines of a text file. From the above examples, we understood how the commands worked with other processes, and commands and a combination of switches as well. The head command does the exact opposite of the tail command.

About Bobbin Zachariah

Founder of LinOxide, passionate lover of Linux and technology writer. Started his career in Linux / Opensource from 2000. Love traveling, blogging and listening music. Reach Bobbin Zachariah about me page and google plus page.

Author Archive Page

Have anything to say?

Your email address will not be published. Required fields are marked *

All comments are subject to moderation.

1 Comment