225

I know there was a command on Unix that I could use to monitor a file and see changes that are getting written to it. This was quite useful especially for checking log files.

Do you know what it is called?

14 Answers 14

285

Do you mean

tail -f logfile.log

?

(Man page for tail)

7
  • 7
    Yes, it's real time. Apr 30, 2009 at 21:06
  • 19
    Sidenote: If your distribution provides the tailf command, use that in preference to tail -f. tailf is more efficient because it doesn't need to access the watched file if it's not being written to (poll accesses are annoying if you mounted the file system with atime updating.) May 2, 2009 at 19:49
  • 11
    At super user I found an answer recommending tail -F instead of -f , too
    – Rafa
    Apr 18, 2012 at 11:17
  • 20
    tail -F will follow filenames rather than file objects, which is especially useful in case of log file rotation. Nov 20, 2013 at 7:19
  • 5
    Update, a few years later: tailf is now deprecated and tail -f is safe. (confirm this on your system with man tailf.) See documentation: man7.org/linux/man-pages/man1/tailf.1.html
    – exp1orer
    Aug 1, 2017 at 17:40
151

You probably meant tail, as per Jon Skeet's answer.

Another useful one is watch; it allows you to run a command periodically and see the output full screen. For example:

watch -n 10 -d ls -l /var/adm/messages

Will run the command ls -l /var/adm/messages every 10 seconds, and highlight the difference in the output between subsequent runs. (Useful for watching how quickly a logfile is growing, for example).

0
79

inotifywait from inotify-tools is useful if you want to run a command every time a file (or any files in a directory) change. For example:

inotifywait -r -m -e modify /var/log | 
   while read file_path file_event file_name; do 
       echo ${file_path}${file_name} event: ${file_event}
   done

output:

Setting up watches.  Beware: since -r was given, this may take a while!
Watches established.
/var/log/messages event: MODIFY
/var/log/kern event: MODIFY
...
3
  • 9
    Just a note that path isn't the greatest choice for a variable name. On zsh, it seems that environment vars aren't case-sensitive. For me, setting path causes PATH to also get set, and that basically means nothing will execute until you fix that. On bash, setting path has no effect on PATH.
    – Thanatos
    Jun 17, 2019 at 6:53
  • 2
    @Thanatos Zsh variables are case-sensitive, but among the variables set by Zsh itself, Zsh "ties" the *PATH variables to an array of the same name, but lowercase. Tied variables always consist of a scalar and an array (e.g. PATH and path), and modifying one modifies the other. A key feature is that the array version is automatically split on the separator in the scalar version (the :). See for yourself with print "$PATH\n$path". The second paragraph in the PARAMETERS USED BY THE SHELL section in the zshparam(1) man page has more detailed information.
    – ZeroKnight
    Mar 10, 2020 at 7:27
  • As a further note, there's quite a few variables used by Zsh that are tied, not just PATH and path. They are all listed in the section in my previous comment including, but not limited to: FPATH/fpath, CDPATH/cdpath, MANPATH/manpath, FIGNORE/fignore, and more.
    – ZeroKnight
    Mar 10, 2020 at 7:33
41

I prefer using less +FG1 over tail -f because I find myself needing to search a log file for a specific error or ID. If I need to search for something, I type ^C to stop following the file and ? to start searching backwards.

Key bindings are pretty much the same as in vi. Any command can be initialized on startup using the + option:

+cmd   Causes  the  specified  cmd  to be executed each time a new file is
       examined.  For example, +G causes less to  initially  display  each
       file starting at the end rather than the beginning.

For really long logs, I find it convenient to use the -n option which turns off line numbering. From the manpage:

-n or --line-numbers
          Suppresses line numbers.  The default (to use line numbers)  may
          cause  less  to run more slowly in some cases, especially with a
          very large input file.  Suppressing line  numbers  with  the  -n
          option  will  avoid this problem.  Using line numbers means: the
          line number will be displayed in the verbose prompt and in the =
          command,  and the v command will pass the current line number to
          the editor (see also  the  discussion  of  LESSEDIT  in  PROMPTS
          below).

1. Hat-tip to rgmarcha for pointing this out in the comments.

3
  • Remember to set an alias with your desired options, so you don't have to type them out every single time. Dec 15, 2015 at 1:48
  • 1
    Actually, you should generally prefer shell functions over aliases in most cases.
    – tripleee
    Oct 3, 2017 at 8:03
  • I would like to know why +FG instead of +F?
    – Steven Lu
    Jun 11, 2020 at 15:11
22

tail is great ... less can also be used start less on the file i.e. less myfile then press Shift+F. This has less act as tail.

1
  • 5
    less +F myfile will make it too
    – rgmarcha
    Jun 4, 2009 at 16:06
20

I'm editing a LaTeX file and wanted to monitor it also for changes somewhere in the middle. I whipped up the following little shell script that proved useful to me. I hope it'll also come in handy to someone else.

#!/bin/bash
FILE="$1"
CMD="$2"
LAST=`ls -l "$FILE"`
while true; do
  sleep 1
  NEW=`ls -l "$FILE"`
  if [ "$NEW" != "$LAST" ]; then
    "$CMD" "$FILE"
    LAST="$NEW"
  fi
done

Save it as watch.sh and do chmod u+x watch.sh. Then I execute it as follows:

./watch.sh file.tex pdflatex

If you want the command only to be run if actual modification takes place, you can use `md5sum "$FILE"` instead of `ls -l "$FILE"`.

1
  • 1
    to watch directories and their contents instead of a single file: NEW=`tree -sDct . -I 'ignore_pattern|another_pattern'`
    – Andy
    Dec 19, 2013 at 14:34
8

you can use the tailf command its very easiest one

tailf logfile.log
6

You can also use inotifywatch/inotifywait which hook into the kernels inotify subsystem. This way you can also watch for things like "open", "close" or "access".

But if you're simply want to get appended lines to stdout i agree on tail.

3

Tail is the standard, traditional, available everywhere unix tool. A little more sophisticated tool is multitail which can monitor several files simultaneously and does syntax highlighting.

3

Forget tailf, diff is the command you want. Here is a good trick to watch the differences as they happen in real time (or close) between 2 files or in one file being written to.

You can use these methods to modify the behavior whatever way you want, such as writing the changes to a file to keep record. Play around with the interval of watch or other options for the commands below.

You have 1 file and you want to watch as changes are made to it:

So heres what to do:

  1. copy the file

    cp file file2
    
  2. write a bash script to find the differences, and update file2

    touch check-differences.sh
    nano check-differences.sh
    chmod 755 check-differences.sh
    
  3. Here's a basic idea for the script. Make it write to a file if you want

    #!/bin/bash
    diff file file2
    cp file file2
    
  4. Next you can either watch the differences on screen using watch

    watch ./check-differences
    

this will update every 2 seconds by default. So if you need to go back and read them, then write the output of diff to a file in the script.

Or use cron to run your script regularly if you don't need to see output.

3

If I want to be able to search around the file in addition to just tailing it, I use less with the "F" command.

When using tail, keep in mind that additional arguments are needed if the file might be rolling over or replaced by edit (default mode for vim's :w).

tail -f <filename> will cause tail to store the file descriptor and follow it. If the file is replaced the descriptor will be changed. The benefit of following the file descriptor is that if the file is renamed, you will still be following it.

tail --follow=<filename> will make tail track the named file by reopening it periodically to see if it has been replaced.

--retry is another useful option if you want to tail a log file but the file hasn't been created yet.

tail -F <filename> is a shortcut for --follow=<filename> --retry.

1

While tail -f somefile.txt keeps scrolling with new data, I sometimes prefer less +G somefile.txt as well to look at a patch of latest data in the file.

1
  • 6
    I think that is all covered in this answer from 7 years ago.
    – kasperd
    Nov 25, 2016 at 21:47
1

I used this, to execute some function on file change:

sudo apt-get install inotify-hookable
inotify-hookable -w ./my_dir_to_monitor  -c "mkdir blabla"
0

tail

The most basic version just uses tail but has the downside of adding all output directly to your terminal:

tail -f path/to/log_file.log

watch + tail (my pick)

I like the following instead so the output doesn't exceed the amount of lines (N) I want to see displayed at once:

watch -n 2 tail -n N path/to/log_file.log

It is better, to me, than using less as it also shows you the command and some more info at the top.

less

However, less is simpler and does let you scroll through the output and automatically fits the number of lines to the size of your screen:

less +F path/to/log_file.log
1
  • See this answer for a version of this that handles carriage returns.
    – Akaisteph7
    Jun 23, 2023 at 17:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .