Harald Dunkel wrote:
> Pádraig Brady wrote:
> > > tail --retry doesn't
> > Oh the file is renamed.
> > You probably need `tail -F` rather than `tail -f --retry`
>
> Please check the man page.
The man page says:
-f, --follow[={name|descriptor}]
output appended data as the file grows;
an absent option argument means 'descriptor'
The behavior of 'tail -f /var/log/messages' is to open the file once
and use file descriptor. Which means that if the file is renamed that
tail follows the renamed file. When the file is renamed to messages.1
then tail -f will be following the messages.1 file.
It also includes this note specific to this situation.
With --follow (-f), tail defaults to following the file descriptor,
which means that even if a tail'ed file is renamed, tail will continue
to track its end. This default behavior is not desirable when you
really want to track the actual name of the file, not the file descrip‐
tor (e.g., log rotation). Use --follow=name in that case. That causes
tail to track the named file in a way that accommodates renaming,
removal and creation.
When used with syslog and logrotate file rotation /var/log/syslog and
/var/log/messages are periodically rotated. A program that opens the
file before rotation will have the open file descriptor pointing to
the rotated file after rotation.
Before rotation (pseudocode):
tail -f /var/log/messages
...internally tail will have fd = open(/var/log/messages) == 3
mv /var/log/messages /var/log/messages.1
...syslog is signaled to open a new /var/log/messages file
...the internal fd remains at 3 and pointing to the messages.1
...this is the tail follows the file descriptor mode
After rotation:
...tail is now following messages.1 file...
After rotation tail will internally still have fd == 3 but that fd
will still be pointing to the original file which has now been renamed
to /var/log/messages.1. But syslog is not writing to the messages.1
file. Syslog is now writing to the newly created messages file which
it was signaled to change output to. messages.1 never gets any new
updates and tail -f never emits any new data.
--retry
keep trying to open a file if it is inaccessible
Using --retry is not appropriate in this situation since tail is
accessing the messages.1 file okay. The file is accessible. But the
renamed file is no longer being written to by syslog.
Strictly speaking the man page says that this is the appropriate
command for following the new file after a renaming of files and
creation of a new file.
tail --follow=name /var/log/messages
However -F is shorter and the --retry makes it robust in the face of
file rotation.
-F same as --follow=name --retry
Hope this helps to explain what is happening.
Bob
Here are the longer details from the full tail documentation.
‘-f’
‘--follow[=HOW]’
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. Note
that the inotify-based implementation handles this case without the
need for any periodic reopening.
No matter which method you use, if the tracked file is determined
to have shrunk, ‘tail’ prints a message saying the file has been
truncated and resumes tracking the end of the file from the
newly-determined endpoint.
When a file is removed, ‘tail’’s behavior depends on whether it is
following the name or the descriptor. When following by name, tail
can detect that a file has been removed and gives a message to that
effect, and if ‘--retry’ has been specified it will continue
checking periodically to see if the file reappears. When following
a descriptor, tail does not detect that the file has been unlinked
or renamed and issues no message; even though the file may no
longer be accessible via its original name, it may still be
growing.
The option values ‘descriptor’ and ‘name’ may be specified only
with the long form of the option, not with ‘-f’.
The ‘-f’ option is ignored if no FILE operand is specified and
standard input is a FIFO or a pipe. Likewise, the ‘-f’ option has
no effect for any operand specified as ‘-’, when standard input is
a FIFO or a pipe.
With kernel inotify support, output is triggered by file changes
and is generally very prompt. Otherwise, ‘tail’ sleeps for one
second between checks— use ‘--sleep-interval=N’ to change that
default—which can make the output appear slightly less responsive
or bursty. When using tail without inotify support, you can make
it more responsive by using a sub-second sleep interval, e.g., via
an alias like this:
alias tail='tail -s.1'
‘-F’
This option is the same as ‘--follow=name --retry’. That is, tail
will attempt to reopen a file when it is removed. Should this
fail, tail will keep trying until it becomes accessible again.
‘--retry’
Indefinitely try to open the specified file. This option is useful
mainly when following (and otherwise issues a warning).
When following by file descriptor (i.e., with
‘--follow=descriptor’), this option only affects the initial open
of the file, as after a successful open, ‘tail’ will start
following the file descriptor.
When following by name (i.e., with ‘--follow=name’), ‘tail’
infinitely retries to re-open the given files until killed.
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.