I have a process that's writing a lot of data to stdout, which I'm redirecting to a log file. I'd like to limit the size of the file by occasionally copying the current file to a new name and truncating it.
My usual techniques of truncating a file, like
cp /dev/null file
don't work, presumably because the process is using it.
Is there some way I can truncate the file? Or delete it and somehow associate the process' stdout with a new file?
FWIW, it's a third party product that I can't modify to change its logging model.
EDIT redirecting over the file seems to have the same issue as the copy above - the file returns to its previous size next time it's written to:
ls -l sample.log ; echo > sample.log ; ls -l sample.log ; sleep 10 ; ls -l sample.log
-rw-rw-r-- 1 user group 1291999 Jun 11 2009 sample.log
-rw-rw-r-- 1 user group 1 Jun 11 2009 sample.log
-rw-rw-r-- 1 user group 1292311 Jun 11 2009 sample.log
Try
> file
.Update regarding the comments: it works nicely for me:
In Linux (actually all unicies) files are created when they are opened and deleted when nothing holds a reference to them. In this case the program that opened it and the directory it was opened 'in' hold references to the file. When the cp program wants to write to the file it gets a reference to it from the directory, writes a length of zero into the metadata stored in the directory (this is a slight simplification) and gives up the handle. Then the original program, still holding the original file handle, writes some more data to the file and saves what it thinks the length should be.
even if you where to delete the file from the directory the program would continue to write data to it (and use up disc space) even though no other program would have any way of referencing it.
in short once the program has a reference (handle) to a file nothing you do is going to change that.
there are in theory ways of modifying the programs behavior by setting LD_LIBRARY_PATH to include a program that intercepts all the file access system calls. I recall seeing something like this somewhere though cant recall the name.
Take a look at the utility
split(1)
, part of GNU Coreutils.I had a similar problem and was unable to do a "tail -f" on the output of a script that was run from cron:
I fixed it by changing the stderr redirect:
As of coreutils 7.0, there is a
truncate
command.I had a similar issue on redhat v6,
echo > file
or> file
was causing apache and tomcat to go faulty as log files would become inaccessible to them.And the fix was strange
would clean the file and not cause any problem.