Linux Commands – tail
Hello Everyone
Welcome to CloudAffaire and this is Debjeet.
In the last blog post, we have discussed head command in Linux which is used to print some lines from the beginning of a file or pipe.
https://cloudaffaire.com/linux-commands-head/
In this blog post, we will discuss tail command in Linux. tail command is used to print some lines from the bottom of the file and output to standard output. By default, tail command prints the last 10 lines of each FILE to standard output. With more than one FILE, precede each with a header giving the file name. You can also use the tail command with a pipe. tail and head commands can be used together to print from any starting point and any ending point.
Linux Commands – tail:
You can use tail command to print some lines from the bottom of a file or pipe. By default, tail prints 10 lines from the bottom of a file or pipe.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
########################### ## Linux Commands | tail ## ########################### ## Prerequisites: One Unix/Linux/POSIX-compliant operating system with bash shell ##----- ## tail ##----- ## tail [options]... [file] ## create a file with 100 lines > myfile; i=1; while [ $i -le 100 ]; \ do echo "$i" >> myfile; ((i++)); done ## create some additional files cp myfile myfile1 cp myfile myfile2 tail myfile ## returns bottom 10 lines tail myfile myfile1 myfile2 ## returns bottom 10 lines of each ## files along with filename as header ps -ax | tail ## also works with pipe |
You can use tail -n K or –lines=K options to output the last K lines. However, if K starts with a ‘+’, tail command starts printing with the Kth line from the start of each file, instead of from the end.
1 2 3 4 5 6 7 |
## tail -n or --lines=[+]NUM option tail myfile ## returns last 10 lines tail -n 20 myfile ## returns last 20 lines tail -n +20 myfile ## start printing from line no. 20 |
You can use tail -c K or –bytes=K options to output the last K bytes, instead of final lines. However, if K starts with a ‘+’, tail starts printing with the Kth byte from the start of each file, instead of from the end. K maybe an integer optionally followed by, one of the following multiplicative suffixes:
- ‘b’ => 512 (“blocks”)
- ‘KB’ => 1000 (KiloBytes)
- ‘K’ => 1024 (KibiBytes)
- ‘MB’ => 1000*1000 (MegaBytes)
- ‘M’ => 1024*1024 (MebiBytes)
- ‘GB’ => 1000*1000*1000 (GigaBytes)
- ‘G’ => 1024*1024*1024 (GibiBytes)
1 2 3 4 5 |
## tail -c or --bytes=[+]NUM options ls -l myfile ## myfile is 292 bytes long tail -c 50 myfile ## returns last 50 bytes of data |
You can use tail -v or –verbose options to always print the filename header. By default, tail prints the filename header only if multiple files were provided as input.
1 2 3 4 5 6 7 |
## tail -v or --verbose options tail myfile ## filename is not printed as header tail -v myfile ## filename is printed as header tail myfile myfile1 myfile2 ## filenames are printed as header |
You can use tail -q or –quiet or –silent options to suppress printing of filename header. By default, the tail does not print the filename header if a single file is provided as input.
1 2 3 4 5 |
## tail -q or --quiet or --silent tail myfile myfile1 myfile2 ## filenames are printed as header tail -q myfile myfile1 myfile2 ## filenames are not printed as a header |
You can use tail -f or –follow[={name|descriptor}] options to loop forever trying to read more characters at the end of the file, presumably because the file is growing. If more than one file is given, ‘tail’ prints a header whenever it gets output from a different file, to indicate which file that output is from.
There are two ways to specify how you’d like to track files with this option, but that difference is noticeable only when a followed file is removed or renamed. If you’d like to continue to track the end of a growing file even after it has been unlinked, use ‘–follow=descriptor’. This is the default behavior, but it is not useful if you’re tracking a log file that may be rotated (removed or renamed, then reopened). In that case, use ‘–follow=name’ to track the named file, perhaps by reopening it periodically to see if it has been removed and recreated by some other program.
You can use tail –follow[={name|descriptor}] with –retry option to indefinitely try to open the specified file. This option is useful mainly when following (and otherwise issues a warning). tail –follow=name –retry option infinitely retries to re-open the given files until killed. tail –follow=descriptor –retry option only affects the initial open of the file, as after a successful open, ‘tail’ will start following the file descriptor. Without this option, when ‘tail’ encounters a file that doesn’t exist or is otherwise inaccessible, it reports that fact and never checks it again. the tail command also supports -F option which is equivalent to –follow=name –retry command.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
## tail -f or --follow[={name|descriptor}] options ## create a script to insert 1 item every 2 second ## and rename the file after some changes cat myscript.sh ----------------------- #!/bin/bash i=1; k=1 > myfile1 while [ $i -le 29 ] do echo "$i" >> myfile$k j=$(($i%10)) l=$(($i%15)) if [ $j -eq 0 ]; then mv myfile1 myfile2; k=2; fi if [ $l -eq 0 ]; then mv myfile2 myfile1; k=1; fi sleep 2 ((i++)) done ----------------------- ## execute the script in background chmod +x myscript.sh ./myscript.sh & tail myfile ## returns the last 10 lines and exit tail --follow=descriptor myfile1 ## displays last 10 lines but does not exit ## new data are appended in in output ## stops at 10, does not reopen the file ## press control + c to exit ./myscript.sh & tail --follow=name myfile1 ## displays last 10 lines but does not exit ## new data are appended in in output ## stops at 20, reopens the file preriodically ## press control + c to exit ./myscript.sh & tail -F myfile1 ## same as --follow=name --retry ## displays last 10 lines but does not exit ## new data are appended in in output ## stops at 20, reopens the file preriodically ## press control + c to exit |
You can use tail –pid=PID option to specify the process ID, PID, of the sole writer of all FILE arguments when following by name or by descriptor. This option causes the tail to automatically terminate when the process terminates. This will work properly only if the writer process and the tailing process are running on the same machine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
## tail --pid=PID option ## modify the script cat myscript.sh ----------------------- #!/bin/bash i=1 > myfile while [ $i -le 30 ] do echo "$i" >> myfile sleep 1 ((i++)) done ----------------------- ./myscript.sh & ## execute the script in background and note the pid ## [1] 4883 tail -f --pid=4883 myfile ## returns 30 lines and automatically exit ./myscript.sh & ## execute the script in background tail -f myfile ## returns 30 lines but does not exit ## press control + c to exist |
You can use tail -s or –sleep-interval=NUMBER options with -f option to change the number of seconds to wait between iterations (the default is 1.0). During one iteration, every specified file is checked to see if it has changed size. However, if you also specify –pid=P option, tail command checks whether process P is alive at least every NUMBER seconds.
1 2 3 4 5 6 7 8 9 10 |
## tail -s option ./myscript.sh & ## execute the script in background and note the pid ## [1] 4962 tail -f --sleep-interval=20 --pid=4962 myfile ## returns 30 lines and then waits for 20 ## seconds before automatically exit ./myscript.sh & ## execute the script in background and note the pid ## [1] 5001 tail -f --pid=5001 myfile ## returns 30 lines and automatically exit |
You can use a combination of head and tail commands to output any number of lines starting and ending from anywhere.
1 2 3 4 5 6 7 8 9 10 11 |
## head and tail command together ## create a file with 100 lines > myfile; i=1; while [ $i -le 100 ]; \ do echo "$i" >> myfile; ((i++)); done head -n 20 myfile | tail -n 10 ## returns line no. 11 to 20 tail -n 20 myfile | head -n 10 ## returns line no. 81 to 90 rm my* |
Hope you have enjoyed this article. In the next blog post, we will discuss touch command in Linux.