5

I am trying to truncate a file, used for redirected stdout. For example:

ping localhost>/tmp/test.log

If I call rm /tmp/test.log then redirection stops but the command works.

If I call truncate -s0 /tmp/test.log or >/tmp/test.log or echo .. and etc. redirection works but the file contains leading zeros because stream position has not changed.

How can I truncate the file?

DavidPostill
  • 162,382
John
  • 51

2 Answers2

3

You need to understand Unix file systems before you can answer this question.

The only thing rm does is erase the files name, effectively a pointer from your directory structure to the disk blocks.

When you run

ping localhost > /tmp/test.log
rm /tmp/test.log

redirection does not stop. The command keeps running, and data keeps accumulating in your disk area. You simply have no way to access this data because you erased its name.

You are free to create a completely unrelated file named /tmp/test.log.

As you noted, by attempting to truncate the file, you get rid of the data that used to be there, but the internal file descriptor knows the position in the file it points to and writes after the end of the file extend the file. Hence the leading zeros.

If you want to "reset" the redirection, then you need to kill the ping program, erase or truncate the /tmp/test.log file, and then restart the ping program.

You could also use a program like rotatelogs

ping localhost | rotatelogs ping.out.%Y%m%d.%H%M 600

to rotate the log file either based on the elapsed time or the size of the file.

hymie
  • 1,276
3

Plan ahead:

  1. Truncate or delete the file, if it exists.
  2. Use >> instead of >.

This way you will take advantage of the fact that >> is essentially "always seek to end of file" while > maintains a pointer to the last written location.

Then you can truncate the file and >> will obey. See this answer of mine, it investigates the exact behavior you need.