69

I have a directory tree that I would like to shred with the Linux 'shred' utility. Unfortunately, shred has no -R option for recursive shredding.

How can I shred an entire directory tree recursively?

9 Answers 9

73

Use the find command to execute shred -uvz recursively:

find <dir> -type f -exec shred -uvz {} \;

-u ensures that after the shred operation is completed, the file is unallocated and removed.

-v enables verbose output for tracking the shred progress

-z performs a final zero-ization of the file to hide that the allocation on disk was shredded.

It should also be noted that shred assumes that the file system overwrites data in-place on disk, which excludes journaled (ext3/4, XFS, etc) and copy-on-write filesystems (btrfs, zfs, etc). This means that shred may not work on a per-file basis for your filesystem.

7
  • Does it work without the -depth option? Does it work on modern, journaling file systems? Dec 17, 2011 at 20:08
  • @userunknown No, shred does not work on modern journaling file systems. For more precise information, please see man shred.
    – FanaticD
    May 10, 2016 at 14:39
  • 5
    Use -exec shred {} + to make it faster since shred accepts multiple arguments.
    – Sumit
    Feb 16, 2019 at 9:10
  • 2
    Changing it to -exec shred --remove=wipe {} + will also attempt to obliterate the filenames - although still with the caveat that it's hard to be sure something is really gone from modern filesystems and storage devices.
    – poolie
    Apr 10, 2020 at 1:43
  • 2
    Adding to @poolie's comment, --remove=wipesync will do what wipe does but additionally ensure the obfuscated bytes are synced to disk. This can be more expensive but makes sure nothing is left behind (keep in mind shred's disclaimer). Note that wipesync is the default behavior if you supply -u. (based on shred version 8.31) Aug 18, 2020 at 19:57
35

Beware of shred!

From the shred-manpage:

CAUTION: Note that shred relies on a very important assumption: that the file system overwrites data in place. This is the traditional way to do things, but many modern file system designs do not satisfy this assumption. The following are examples of file systems on which shred is not effective, or is not guaranteed to be effective in all file system modes:

  • log-structured or journaled file systems, such as those supplied with AIX and Solaris (and JFS, ReiserFS, XFS, Ext3, etc.)

  • file systems that write redundant data and carry on even if some writes fail, such as RAID-based file systems

  • file systems that make snapshots, such as Network Appliance's NFS server

  • file systems that cache in temporary locations, such as NFS version 3 clients

  • compressed file systems

In the case of ext3 file systems, the above 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. Ext3 journaling modes can be changed by adding the data=something option to the mount options for a particular file system in the /etc/fstab file, as documented in the mount man page (man mount).

In addition, file system backups and remote mirrors may contain copies of the file that cannot be removed, and that will allow a shredded file to be recovered later.

Also, SSDs might thwart your attempts of overwriting data.

Solution: Use an encrypted filesystem, and just delete your files.

5
  • +1 for pointer on shred, I had a similar case before. It did not work on NetApp's NFS. NetApp uses WAFL and which uses copy-on-write including metajournalling, so its right. Also with latest Solaris' ZFS is another case where shred sheds. Dec 17, 2011 at 20:26
  • 10
    This is a bad solution. An encrypted file system is only safe so long as it locked (and so unmounted). As soon as your OS is up and running, the data is up-for-grabs.
    – oleks
    Sep 17, 2015 at 12:30
  • 4
    @oleks: Both the usage of shred and data encryption prevent reading the data off an offline storage device (think theft or police) with data encryption having the added benefit of protecting all files, not just the ones (properly) deleted. Once the file system is mounted we're back to good ol' unix permissions in either case and data protection becomes a task of OS security and proper system administration again. Upfront filesystem encryption is definitely not worse at protecting data at rest than strategic usage of shred!
    – ntninja
    Aug 8, 2018 at 14:12
  • 3
    This doesn't really answer the question, which is about someone who does already have files they want to shred.
    – poolie
    Apr 10, 2020 at 1:40
  • How could companies ever practically comply with GDPR if file- and operating systems make it so hard and untransparant to destroy information.
    – Herbert
    Jan 8 at 15:06
28

Use secure delete instead.

sudo apt-get install secure-delete
srm -r pathname

Done. Secure delete is a lot more paranoid than shred, using 38 passes instead of 3. To do a fast single pass, use

srm -rfll pathname

fll gets you a less random data generator, and only a single pass.

5
  • Does it solve the issue mentioned in unix.stackexchange.com/a/27075/18886 ?
    – Ian Dunn
    Nov 8, 2016 at 16:17
  • 1
    How could it? No
    – Cookie
    Nov 8, 2016 at 16:31
  • Note that this method has the additional benefit over the proposed find-based methods that will try to also erase stored filenames by renaming files before truncating and unlinking them.
    – ntninja
    Aug 8, 2018 at 13:58
  • @ntninja find-based methods use shred and shred does rename files before finishing to delete them. So same benefits right?
    – tuxayo
    Jul 4, 2019 at 9:14
  • 1
    srm -rfll v3.1 seems noticeably slower than the find -exec shred alternatives, as if it is still syncing even though asked not to.
    – poolie
    Apr 10, 2020 at 1:44
15

Combining this answer with the best known options for shred using this stack overflow link 'Deleting Files Permanently and Securely on CentOS':

find <directory> -depth -type f -exec shred -v -n 1 -z -u {} \;

Edit: Be aware that best answer for shredding a single file forces a sync which writes changes to the media before deleting the file because some or all journaled filesystems have a buffer.

If possible, the find command should call a shell script on the file which runs:

shred -v -n 1 /path/to/your/file #overwriting with random data
sync #forcing a sync of the buffers to the disk
shred -v -n 0 -z -u /path/to/your/file #overwriting with zeroes and remove the file

on each file.

4
  • After reading and researching many answers, I found (imho) this answer to be the most thorough. I would only add to it that since shred does not remove directories I appended rm -rvf $1 to the shell script (where $1 is the /path/to/your/file passed in from the {} expansion in the find... -exec)
    – JoelAZ
    Jul 4, 2014 at 5:44
  • 6
    shred already does a fsync(2) after each pass. Precisely because you need to force the file changes to reach the disk before the next pass.
    – Ángel
    Jan 2, 2016 at 15:49
  • What does depth do here? Also unsure about the trailing backslash
    – geneorama
    Dec 12, 2018 at 17:04
  • -depth is usually used to reverse order of showing dir name match and file match inside that dir. If dir comes first and you delete it, you can't continue with files inside it anymore. With '-depth' dir itself will be listed after all its files if it matches. It does not make sense to use it together with -type f, but it will do no harm and with it, if sometime later you add rm -r, you'll avoid wasting time on an error. '\' is still the good old escape character. Used for ';' as shell would like to steal it, but it belongs to 'find'. Also ';' would do instead of \;
    – papo
    Oct 8, 2020 at 14:15
7
find /your/directory -exec shred {} \;
2
  • Upvoted, but James beat you by one minute for the accept.
    – Steve V.
    Dec 17, 2011 at 6:19
  • Does it work without the -depth option? Does it work on modern, journaling file systems? Dec 17, 2011 at 20:08
6
find [dirname] -depth -type f -exec shred -n1 {} \;

This performs a depth-first search for files in directory [dirname], then runs the shred -n1 command on each file. When removing files and/or directories, adding -depth as default is a good habit, even though it's not strictly needed for this case. When running this sort of command with rm -rf instead of shred, -depth is needed to ensure that directories are not deleted before the contents of the directories are attempted to be deleted (thus causing errors).

0
1

Note that shred is an utility from GNU coreutils, it has nothing to do with Linux, other than Linux being just a kernel, operating systems using that kernel need to pick other software from elsewhere, and the GNU project has historically been the primary source for most. For basic utilities, busybox and toybox are other options and both happen to also include a shred utility with an interface designed after the GNU implementation though with a reduced feature set.

Now, several things to take into consideration:

Files on Unix-like systems can be of several different types: regular, fifo, directory, symlink, device, socket... All except socket can be opened, most can be read and written, but not all of them you'd want shred to shred when going through the list. In particular,

  • opening a symlink opens the target of a symlink, so letting shred shred arbitrary symlinks could lead you to shred any file on the filesystem.
  • Shredding /dev/sda would shred the whole contents of a disk
  • a fifo is an inter-process communication tool, writing random data there would not make sense. The GNU implementation of shred rejects files of type fifo.

You likely want to only shred files of type:

  • regular
  • directory (if the file names are also sensitives).

But for the latter, while GNU shred has a --remove=wipe for that, it can only do it for one directory entry, so couldn't do it for the other entries (including the ones for files of different types, or the entries that have been removed without being wiped before).

It's also not possible to selectively shred files of a given type in a race-free way. For instance, you could determine a file is a regular file, but that file be replaced with a symlink by the time shred is invoked to wipe it.

Also note that if some of the files are being actively written, shred will fail to wipe the parts that have been written after it was invoked.

So, the best you can do with GNU shred is:

find dir -depth ! -type f -delete -o -exec shred -f --remove=wipe {} ';'

So besides all the limitations with shredding already mentioned by others, the limitations with this recursive shredding approach are also:

  • it will not fully shred directory contents (the name of the files within).
  • it may not full shred files that are still being written (even if they are deleted)
  • it could end up shredding files of the wrong type. You'd want not to do that on directories writable by others as that could introduce security vulnerabilities.
0

The most thorough shred method I've found, which includes directory removal too, is to have find call a script to have shred:

  • overwrite the file
  • sync
  • then delete
  • and finally call rm to remove the directory names.

This method also properly handles filenames with spaces in them.

First - the shred script (I've named mine dirShredder.sh and stored it in the /root directory:

shred -v -n 1 "$1" #overwriting with random data
sync #forcing a sync of the buffers to the disk
shred -v -n 0 -z -u "$1" #overwriting with zeroes and remove the file
rm -rvf "$1" # call rm to remove the directories

Then, call the script like this:

find /volume1/pathToShred/ -mindepth 1 -depth -exec /root/dirShredder.sh "{}" \;

Make sure to mark the killit.sh file executable (chmod +x) and of course update the path for the dir you want to shred and to dirShredder.sh if you store it somewhere else.

NOTA BENE - shred has issues on Copy-on-Write filesystems (ZFS, BTRFS, et al) and even on Journaling file systems. There is no real accepted "best" way to deal with this that I've found other than "encrypted filesystems" but I'm not sure how effective this is after-the-fact.
The closest it seems you can get is to overwrite all empty space on the drive with random data after your shredding ops (not zeros, seems this is not always reliable.) Also, SSDs may have other considerations too (like TRIM.)

I'm not going into those here, there are other Stack answers (@user unknown's answer in this question for example) and plenty of discussions throughout the 'net that cover these topics so search them out if you need that level of security.

-1

Use

shred yourDirectory/*

Go check your file, they're unreadable :)

rm -r yourDirectory
2
  • 1
    The issue here is that shred is only applied to the visible entries at the first level under yourDirectory whereas the question asks how one may apply it to all files in a hierarchy.
    – Kusalananda
    Aug 13, 2023 at 11:22
  • 1
    That only shreds the non-hidden files directly in yourDirectory, not the ones in subdirectories and it fails to shred the hidden ones unless you change the default behaviour of your shell globs to include them. Aug 13, 2023 at 11:22

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .