Emptying the contents of a text file

The simplest way:

> filename

This is a less obvious way and probably less readable in a shell script by others, but it's all you need.

Because > is not actually a really command (it is bash builtin) you can't use:

sudo > filename

when you don't have permissions on that file. But you can use:

sudo bash -c "> filename"

There is a tool created for that purpose:

truncate -s 0 filename

This will clear the contents but it will still be the same file (the inode stays the same).

Suppose you "empty" a file using the naive method of deleting and recreating the file: the new file will (usually) have a new inode.

This inode is important because some programs hold a handle to the file "by inode". Even after you deleted and recreated a file those programs will still have the old file with the old content. The program holds the old file via the old inode while your recreated empty file has a new inode.

Some links to more details at the end of this answer.


Another way, maybe easier to remember:

echo -n > filename

This also keeps the same inode.

Note that both truncate and echo -n are not defined by POSIX.

For POSIX compliance use cat /dev/null:

cat /dev/null > filename

Yet another way, more obscure and probably not shell agnostic:

> filename

If the file to truncate needs root privileges to write then the following lines will not work as you might expect:

# following commands do not work
sudo echo -n > filename
sudo cat /dev/null > filename
sudo > filename

This is because the redirection is done by the shell even before sudo is executed. That means that the write access to the file is done using the privileges of the user who runs the shell, not the privileges which will be granted by sudo.

A workaround is to defer the redirection to a shell executed using sudo privileges like this:

sudo sh -c "echo -n > filename"

Using truncate you do not need such a workaround because the write access is not done by the shell but by truncate which is executed by sudo using sudo privileges.

sudo truncate -s 0 filename

For some gory details about programs holding the file open even if the file has been deleted you can read the following:

  • https://stackoverflow.com/questions/2028874/what-happens-to-an-open-file-handler-on-linux-if-the-pointed-file-gets-moved-de
  • https://serverfault.com/questions/501963/how-to-recover-free-space-on-deleted-files-without-restarting-the-referencing-pr
  • https://unix.stackexchange.com/questions/182077/best-way-to-free-disk-space-from-deleted-files-that-are-held-open
  • https://stackoverflow.com/questions/51019714/does-recreating-a-file-reuse-the-previous-inode

To automate this you can use logrotate. Just create a configuration file for the file you want to be emptied, add other settings and you can have it empty every day automatically based on criteria you choose f.e everyday, or when file is bigger than etc.

Take a look here on how to configure logrotate: http://linuxcommand.org/man_pages/logrotate8.html


echo "" > foo_file is a simple way of doing that, it will replace all contents of foo_file with "" making it in this case, empty.

You can also use cat /dev/null > foo_file, that will read the null device and overwrite your file with nothing at all.