Search code examples
linuxbashtail

Tail the most recent file


I have a program that logs its output to an *.out file when running. I set up a bash script to run several different times, so each run writes to a different *.out file. I found that I could tail the most recent *.out file like this:

watch tail $(ls -tr *.out | tail -n1)

The problem seems to be that the referencing $() only gets executed once. So when the first run finishes, watch continues to tail the same *.out file, even though there is now a newer *.out file.

How can I alter this to go to the next *.out file after one run finishes?

I tried doing some nesting of quotes and parentheses, but I don't really understand the details of referencing. Matters are complicated by the fact that watch passes its command to sh, even though I'm using bash.

Bonus points: it would be great if this could be modified to tail -f instead of just repeating watch every n seconds.


Solution

  • I also dealt with this problem and finally came to this solution:

     watch "ls -t1 | sed q | xargs tail"
    

    Need to get a bit hacky for the bonus. The tail command also supports an argument --pid which makes tail die as soon as the referenced PID dies. Sounds good? Here's some pattern you could use:

    while true; do ls -t1 | sed q | xargs lsof -F np | sed 's/.\(.*\)/\1/g' | xargs tail -f --pid 2>/dev/null ; done
    

    This basically tracks the most current file and restarts tail when the file writing process ends.