Truncating a file while it's being used (Linux

2019-01-13 20:25发布

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

13条回答
狗以群分
2楼-- · 2019-01-13 20:54

Try > file.


Update regarding the comments: it works nicely for me:

robert@rm:~> echo "content" > test-file
robert@rm:~> cat test-file 
content
robert@rm:~> > test-file
robert@rm:~> cat test-file 
查看更多
小情绪 Triste *
3楼-- · 2019-01-13 20:55

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.

查看更多
淡お忘
4楼-- · 2019-01-13 20:59

Take a look at the utility split(1), part of GNU Coreutils.

查看更多
你好瞎i
5楼-- · 2019-01-13 20:59

I had a similar problem and was unable to do a "tail -f" on the output of a script that was run from cron:

    * * * * * my_script >> /var/log/my_script.log 2>&1

I fixed it by changing the stderr redirect:

    * * * * * my_script >> /var/log/my_script.log 2>/var/log/my_script.err
查看更多
\"骚年 ilove
6楼-- · 2019-01-13 21:02

As of coreutils 7.0, there is a truncate command.

查看更多
孤傲高冷的网名
7楼-- · 2019-01-13 21:07

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

echo " " > file

would clean the file and not cause any problem.

查看更多
登录 后发表回答