Empty the contents of a file
I am aware of three methods to delete all entries from a file.
filename < /dev/null
Of these three I abuse
>filenamethe most as that requires the least number of keystrokes.
However, I would like to know which is the most efficient of the three (if there are any more efficient methods) with respect to large log files and small files.
Also, how does the three codes operate and delete the contents?
Very similar to Difference between cat and '>' to zero out a file where you'll find more information.
The first will work only if called from bash command line, but won't work if executed in a .sh file
Actually, the second form
touch filenamedoesn't delete anything from the file - it only creates an empty file if one did not exist, or updates the last-modified date of an existing file.
And the third
filename < /dev/nulltries to run filename with
cp /dev/null filenameworks.
As for efficient, the most efficient would be
truncate -s 0 filename; see here: http://linux.die.net/man/1/truncate.
cp /dev/null filenameor
> filenameare both fine. They both open and then close the file, using the truncate-on-open setting.
/dev/null, so that makes it marginally slower.
On the other hand,
truncatewould likely be slower than
> filenamewhen run from a script since running the truncate command requires the system to open the executable, load it, and the run it.
The truncate operation uses the ftruncate() or truncate() system call which does not bother to open the file. It also avoids the close() system call that cp and `> filename` methods need to call.
Actually, it (at least the GNU one) does an open+ftruncate+close (in addition to the many system calls it does to load and initialise itself), as anyway, it would have to create the file if it didn't exist and `truncate(2)` doesn't do that.
If we use `touch filename`, will the inode remain same (provided there was a file before)?
I get this error `truncate: not found.`. What is the next best option since I cannot add the truncate function to this environment.
// , Doesn't `cp /dev/null filename` lose the file ownership and permissions?
/dev/null is owned by root and has very open file permissions, so that's probably a good thing. It will use the default settings (based on umask) when creating the new file.
The nice thing about truncate is that you can do it on multiple files in a single command without complicating things with `xargs` etc
I feel `>filename` is the most efficient, because its faster to type. `truncate` may be technically faster, but it will never really be faster than `>` because you'll have to type out `truncate -s 0 filename`.
@aalaap - if we're talking about speed of typing out commands, then I agree with you, that's probably about as fast as you can get. When talking about efficiency of the operation itself, such as when trying to keep down the overhead of truncating very rapidly (such as > 100 times per second), then the answer is very different.
@ash Yes, I understand that. I was talking about a practical, real-world comparison between the two.
@aalaap your comment is not necessarily practical. If I have to truncate often, I would just function it to a short alias, and the keystroke count would be similar, so not an issue. However, if I do have to truncate very often, as on the order of 10k files, the issue of keystrokes is negligible compared to runtime.
Interestingly, it does not seem to work with ZSH: ```> log/test.log # ==> zsh: file exists: log/test.log```