5

In a few spots I got this to work

ls -rt /path/to/log/file/ | tail -1 | xargs tail -f

But I can't figure out why it won't always work
(This is quick fix until I get the log rolling fixed here)

12

Sort command and THE most recent log file

Why using -r (reverse sort order) than reaching end of output with tail?

Using normal sort order and take first entry would be quicker!

tail -f `/bin/ls -1td /path/to/log/file/*| /usr/bin/head -n1`

or

tail -f $(/bin/ls -1t /path/to/log/file/* | /bin/sed q)

work fine.

Nota: I like to use sed because this command is present in /bin, maybe before /usr are mounted.

tail -f `/bin/ls -1tr /path/to/log/file/* | /bin/sed -ne '$p'`

would work but, as already said: inversing sort order, than dropping whole ouput for using only last entry is not a real good idea ;-)

Warning, in last directory, * have to not match a directory, or else command tail won't know how to open it.

Same but using find for searching for most recent file:

read -a file < <(
    find /tmp 2>/dev/null -type f -mmin +-1 -mmin -10 -printf "%Ts %p\n" |
    sort -rn)
tail -f ${file[1]}

Note:

  • the -mmin +-1 ensure to not list bad timed files: in the futur.
  • read is builtin, create an array and prevent the use of head -n1| cut -d \ -f2
  • -mmin -10 could be changed or suppressed, but this prevent long sort process.

But tail support to watch about more than one file:

Try to open two shell console and try this:

In 1st console:

user@host[pts/1]:~$ touch /tmp/file_{1,2,3}
user@host[pts/1]:~$ tail -f /tmp/file_{1,2,3}
==> /tmp/file_1 <==

==> /tmp/file_2 <==

==> /tmp/file_3 <==

in second one, while keeping 1st console visible, hit many time:

user@host[pts/2]:~$ tee -a /tmp/file_$((RANDOM%3+1)) <<<$RANDOM
25285
user@host[pts/2]:~$ tee -a /tmp/file_$((RANDOM%3+1)) <<<$RANDOM
16381
user@host[pts/2]:~$ tee -a /tmp/file_$((RANDOM%3+1)) <<<$RANDOM
19766
user@host[pts/2]:~$ tee -a /tmp/file_$((RANDOM%3+1)) <<<$RANDOM
3053

1st console could look like:

==> /tmp/file_2 <==
25285

==> /tmp/file_1 <==
16381
19766

==> /tmp/file_3 <==
3053

...

In the idea of SO question, but time based, multi files

By using find command, we could watch on last minutes modified files -mmin or last days -mtime:

find /path/to/logdir -type f -mmin -10 -exec tail -f {} +

for watching for logfiles modified last 10 minutes.

Note:

  • Have a look at man tail, about
    • -F option for long time watch
    • -q option for not printing file names

Fancy formatting

find /path/to/logdir -type f -mmin -10 -exec tail -f {} + |
    sed -une 's/^==> .path.to.logdir.\(.*\) <==$/\1             /;ta;bb;
               :a;s/^\(.\{12\}\) *$/\1: /;h;bc;
               :b;G;s/^\(..*\)\n\(.*\)/\2 \1/p;:c;'

Where you could modify .path.to.logdir. and change 12 for more suitable length.

For sample, keeping our two console, stop 1st and try

user@host[pts/1]:~$ find /tmp/ -type f -mtime -1 -name 'file_?' -exec tail -f {} + |
    sed -une 's/^==> .tmp.\(.*\) <==$/\1             /;ta;bb;
        :a;s/^\(.\{12\}\) *$/\1: /;h;bc;
        :b;G;s/^\(..*\)\n\(.*\)/\2 \1/p;:c;'
file_2      :  25285
file_1      :  16381
file_1      :  19766
file_3      :  3053

than in second console, hit again some

user@host[pts/2]:~$ tee -a /tmp/file_$((RANDOM%3+1)) <<<$RANDOM
3

This will not work unless you are in /path/to/log/file, because ls gives you only the name of the file and tail -f won't find it. If you put a * in the end of the ls it will give you full paths:

ls -rt /var/log/apache2/* | tail -1 | xargs tail -f
2

The easiest solution is to use zsh and take advantage of the glob qualifiers om to sort by modification time (most recent first) and [1] to retain only the first match.

tail -f /path/to/log/directory/*(om[1])

If you don't have zsh, install it. If you really don't want to install zsh, it's not too bad with ls, provided that your file names don't contain any special characters (anything nonprintable is calling for trouble here), which should be ok for log files. Note that as Paylo Almeida already remarked you can't just use the output of ls /path/to/log/directory since that displays paths that are relative to /path/to/log/directory. You can change to that directory first:

cd /path/to/log/directory
tail -f "$(ls -t | head -n 1)"

Or you can add the path:

tail -f "/path/to/log/directory/$(ls -t /path/to/log/directory | head -n 1)"

Or you can get ls to print full paths:

tail -f "$(ls -t /path/to/log/directory/* | head -n 1)"

The tail command will keep following the same file forever, even if a more recent log file is created afterwards. If you want to automatically switch to a different file, you need a more sophisticated approach, where you detect new files and start a new instance of tail on the new file. Under Linux, you can use the inotify interface.

while true; do
  tail -n +1 -f /path/to/log/directory/*(om[1])
  inotifywait -qq -e create /path/to/log/directory
  kill $!
done
-1

Go to the event logs directory and give tail -f * to view all the recent logs.

  • That is not at all what the question asked. – Gilles Jul 23 '13 at 1:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.