Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

An application I am developing locally logs it's output to files formatted with the current timestamp such as app-%Y%m%d.log.

To make it simple to be able to tail the current's day log in a terminal window, I have a symlink named current.log which points to today's log.

At the start of work each day, I need to kill the tail process, point the symlink at today's file, and then re-run the command to tail -f current.log.

Is it possible to change the target of the symlink without having to restart tail - by changing the target of the file handle without tail being any wiser?

To automate this "start of new work day" task it would be easy to setup a cron'ed script to point the symlink at today's file, but it seems that the existing tail process would have no idea that the target has changed.

share|improve this question
    
The operating system abstraction you refer to as "handles" are better referred to as "file descriptors". It's hard to tell, given the state of Microsoft's documentation, but "descriptors" and "handles" are probably different at some level. –  Bruce Ediger Apr 1 '11 at 15:35
1  
One way to work around this is to additionally log to a fifo and then xconsole from the fifo. –  JodieC Mar 24 '12 at 3:31
add comment

6 Answers 6

up vote 5 down vote accepted

I don't think that is possible, unless you can get tail to close and reopen the file periodically. One tail (or any other program) opens a file, it gets a handle to the inode of that file. At that point, filenames and links are no longer consulted. That is why you can delete a file from the filesystem, and any program that has that file open will continue to work. Its is only when the ;ast program closes the file that it actually gets removed from disk.

Update: At least the version tail on OS X has a -F option, which will reopen the file if it has moved.

share|improve this answer
    
Ubuntu has -F (or --follow=current.log --retry) as well –  charlesbridge Apr 1 '11 at 18:39
1  
tail -F also works fine in Fedora; the hint about OS X gave me enough of a hint to check it out on my system. This is the best answer at achieving what I want to do (keep tailing a file even if it changes names); seems pretty clear the answer to my root question about symlinks is "no". Thanks! –  matt b Apr 1 '11 at 20:19
    
tail -F works for me in ubuntu. –  frankadelic Jan 15 '13 at 20:31
add comment

I prefer to use a short perl script instead of /usr/bin/tail -f for that purpose.

See http://search.cpan.org/~mgrabnar/File-Tail-0.99.3/Tail.pm for hints.

share|improve this answer
add comment

Once a program has open the file, it keeps accessing that same file, even if the file is moved or even deleted. (Removing an open file only removes its name; the file — the inode — is actually deleted once no process has it open.)

Some programs watch if something happens to the file they have open. For example, the classic program tail -f keeps printing lines appended to the same file; some modern implementations (GNU, FreeBSD, NetBSD, OSX) have tail -F, which detects if a new file with the same name is moved into place and starts reading from the new file. Multitail can do that as well (run it as multitail --retry).

You can use the Inotify interface on Linux, or its equivalent on other unices, to detect if a file has changed. On Linux, use the inotifywait command.

share|improve this answer
add comment

Why not log to a file, current.log which you can tail -f to your hearts content, and then use something like /usr/sbin/logrotate to rotate that file. You can specify in the config that you'd like to do some postrotate commands to rename the old file with the date appended, etc. It removes the need for symlinks completely and may also simplify your logging code.

Of course, logrotate may not be installed on the system you are developing for.

share|improve this answer
add comment

If you're on a modern linux, you could use inotifywait, one of the command line programs from the inotify-tools package. I haven't done this, but it looks like inotifywait could be used in a shell script to reset the symlink and stop and restart tail -f on the symlink. You might even be able to dispose of the symlink, and just tail the current log file.

Without using inotify, it is possible to write your own tail-like program that checks to see if the inode number of the filename it reads from has changed. At that point, the tail-like program can close it's old file descriptor, and get a new file descriptor for the now-different filename. This is a tricky program to write, and it's prone to race conditions.

share|improve this answer
add comment

From your description it sounds like your specific circumstance could be solved by making a cron job which also killed/restarted the tail process. But in general, (Mac OS being the exception) tail will remember where you are in the file (that is, the byte offset). Also, the open file handle points to the target file, not the symlink. The symlink becomes irrelevant to the reading process once the file has been opened. Although it's possible to have features which reopen the file based on the original path when something changes, most implementations don't do this.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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