How to completely erase a file on Linux

As we have seen, simply deleting a file with a file manager or with ‘rm’ is not enough to really remove it from your hard disk and it is still possible to recover a deleted file.
Good news if you delete a file accidentally, but what can you do if you are in the opposite situation and you actually need to make sure that the file you are deleting doesn’t have chance to be recovered?
Fortunately in Linux there are some tools dedicated to totally erasing the file data: Shred and Wipe

First an important warning: while these tools make it harder to recover any data they erase, technically it is still NOT fully impossible to do so. The only safest way to lose the data is to physically obliterate the hard drive.
Now, assuming that you are not a big corporation with important trade secrets or a government official with top-secret information, let see how you can “safely” remove your data.
Shred
Shred overwrite the given file repeatedly, in order to make it harder for even very expensive hardware probing to recover the data.
The basic way to use it is:
shred filename
With the above syntax shred will, as mentioned, overwrite the content of the file several times (3 if not specified differently) without deleting it.
For example, create a file with some text in it:
echo "This is a very important string of text." > test.txt
And check it:
cat test.txt
This is a very important string of text.

And now try to shred it:
shred test.txt
If you check again the content of the file, you will now find some random text:
cat test.txt
°Ûc¶Yâ½öÌIXU½+M*ÅÒd>ú]²ûþ¨Zë¡7îW
....(and so on for several lines)

If you want to do perform more than 3 passes you can use the ‘-n X’ flag, where X is the number of passes you want.
To delete the file after the shredding you have to add the ‘-u’ flag and to see all the steps you have to add ‘-v’.
shred -vu test.txt
shred: test.txt: pass 1/3 (random)...
shred: test.txt: pass 2/3 (random)...
shred: test.txt: pass 3/3 (random)...
shred: test.txt: removing
shred: test.txt: renamed to 00000000
shred: 00000000: renamed to 0000000
shred: 0000000: renamed to 000000
shred: 000000: renamed to 00000
shred: 00000: renamed to 0000
shred: 0000: renamed to 000
shred: 000: renamed to 00
shred: 00: renamed to 0
shred: test.txt: removed

WARNING (as reported by the shred manual): Shred relies on a very important assumption: that the file system overwrite data in place. This is the traditional way to do things, but many modern file system designs do not satisfy this assumption, for example In the case of ext3 file systems, the disclaimer applies (and shred is thus of limited effectiveness) only in data=journal mode, which journals file data in addition to just metadata. In both the data=ordered (default) and data=writeback modes, shred works as usual.
Wipe
Wipe is a secure file wiping utility. Unlike Shred, Wipe is not usually installed by default, but fortunately it can be easily found in the repositories of most Linux distributions.
Some useful flags of Wipe are:
-f: force the wipe suppressing the confirmation request;
-r: remove the entire directory specified with all the files and subdirectories contained within; symbolic links are not followed;
-v: verbose output;
-p: the number of passes.
So for example:
wipe -f -p32 test.txt
will delete the file with 32 passes.
WARNING (as reported by the Wipe manual): for Wipe to work there must be some sort of write barrier between passes. Wipe uses fdatasync(2) (or fsync(2)) as a write barrier, or if fsync(2) isn’t available, the file is opened with the O_DSYNC or O_SYNC flag. For wipe to be effective, each pass must be completely written. To ensure this, the drive must support some form of a write barrier, write cache flush, or write cache disabling. SCSI supports ordered command tags. IDE/ATA drives support write cache flushes and write cache disabling. Unfortunetly, not all drives actually disable write cache when asked to. Those drives are broken. Write caching should always be disabled, unless your system is battery backed and always powers down cleanly.