by Allen Fung, Senior Software Engineer
“tail -F” is commonly used to monitor files for updates.
Here’s how tail can be used to monitor multiple files at once.
$ tail -F file1 file2
The problem with the command above is that the text written to file1 and file2 might not be flushed to disk at new line boundaries. As a result, text from one file could be spliced into text from the other file in the output of tail.
Here’s an example of the problem. Suppose that the following is written to file1.
line_1
line_2
line_3
Also, suppose that the following is written to file2.
LINE_A
LINE_B
LINE_C
If text is not flushed at new line boundaries, it will be possible to get the following output from tail.
lineLINE_A
_1
LINE_B
line_2
LINE_C
line_3
As you can see, “LINE_A” is spliced into “line_1”, resulting in “lineLINE_A” in the first line. Here are a few ways to resolve the problem above.
Run multiple tails in parallel and pipe the output of each tail to grep. You will need to use the option in grep to print only at new line boundaries.
Write a new tail that only prints when it receives a complete line from a file.
Modify the application that generated the log files to create only a single log file. You will need to make sure that text is flushed to the single file at new line boundaries.
Here’s the code to implement (1) above.
$ vi multi-tail.sh
#!/bin/sh
# When this exits, exit all background process also.
trap ‘kill $(jobs -p)’ EXIT
# iterate through each of the given file names
for file in “$@”
do
# Tail file in background.
tail -F $file | grep –line-buffered “” &
done
# wait .. until CTRL+C
wait
I’ll leave it to the reader to implement (2) and (3).
Thanks for reading!