3

This is along the lines of How to start tailing a file that has not been yet created with a twist: a file with the name already exists.

I have a program that is run multiple times; when the output file name is already in use, it renames the extant file by inserting _XYZ before the file extension where XYZ is the smallest integer (e.g., output.out becomes output_001.out, or output_002.out if output_001.out already exists, etc.), and creates a new output file with the primary name.

If I tail the primary name, even with -F, it begins tailing the extant file immediately and retains the handle to that inode even when the file is renamed, ignoring the new file.

The program is run on a shared cluster with queue management, so execution begins with long & variable lags.

Is it even possible to tail the new file without waiting for it to be created first? If so, how?

  • Yep, same issue; I skipped it in my 'literature review' because I didn't understand the title. Now I've learned two things today. – Ghillie Dhu May 01 '13 at 19:39
  • Additionally you can skip using tail and accomplish something similar with less. See this Q&A: http://unix.stackexchange.com/questions/74279/how-do-i-less-a-filename-rather-than-an-inode-number/74283#74283. I learned how to use this one yesterday 8-). – slm May 01 '13 at 19:46

1 Answers1

3

tail -F should already do this.

Create an empty /tmp/t/file. Then, in terminal 1, start tail -F, and leave it running:

anthony@Zia:~$ tail -F /tmp/t/file
a
b
tail: `/tmp/t/file' has become inaccessible: No such file or directory
tail: `/tmp/t/file' has appeared;  following end of new file
c
d

In terminal 2, I did:

anthony@Zia:/tmp/t$ echo a >> file
anthony@Zia:/tmp/t$ echo b >> file
anthony@Zia:/tmp/t$ mv -i file file.old; echo c >> file
anthony@Zia:/tmp/t$ echo d >> file

As you can see, tail -F does indeed follow the name, not the inode. Maybe you're using a tail that gives different meaning to -F (that flag is a BSD extension, copied later by GNU as well), or your version is buggy? You could also try tail --follow=name --retry (GNU tail alternate syntax) or xtail (which tails an entire directory).

derobert
  • 109,670
  • OK, I feel like an idiot. I retested & it works as advertised; .bash_history reveals I fat-fingered the first test with -f instead of -F. – Ghillie Dhu May 01 '13 at 17:36
  • Note that the -F option comes from BSDs (NetBSD first, then FreeBSD in 1998. GNU tail added a --follow=name later (textutils 1.22g 1999) and the -F option for compatibility with BSDs even later (textutils 2.0.15 2001). – Stéphane Chazelas May 01 '13 at 19:12
  • @StephaneChazelas BSD isn't the only non-GNU tail, but thanks for the history behind it—I didn't know it, and find it interesting. And indeed, it turned out to be something else... Typo for the win :-( – derobert May 01 '13 at 20:44
  • Yes, I was just pointing out that -F was not a GNUism in response to your using a non-GNU tail. – Stéphane Chazelas May 01 '13 at 20:45
  • @StephaneChazelas Indeed, you're right, I've given the wrong impression in my answer. Updated to correct. Please feel free in general to edit my answers to fix things like this. – derobert May 01 '13 at 21:05