Welcome, guest | Sign In | My Account | Store | Cart

When files and directories need to be securely deleted, there are many tools in existence that people can turn to for their needs. While there are many ways one might go about manually deleting files and removing directories, this recipe provides a sample implementation of what may be considered throughout the process. This destructive command line program takes the path to a directory as a command line argument and does its best to render it and its contents unrecoverable. There are much better and inclusive applications than this one, but those wishing to write their own utilities may take some inspiration from this recipe while writing their own tools.

If there are any recommendation for this recipe or if anyone wishes to down-vote this recipe, please provide corrective criticism showing the the program's faults and give suggestions on how you would fix any problems that it might have.

Python, 59 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
from os import path, walk, rename, urandom, remove, rmdir
from sys import argv
from uuid import uuid4

################################################################################

def main():
    "Test arguments and either destroy path or print help."
    if len(argv) == 2 and path.isdir(argv[1]):
        destroy(argv[1])
    else:
        print('Usage: {} <directory>'.format(path.basename(argv[0])))

def destroy(directory):
    "Render the directory with its contents unrecoverable."
    for root, dirs, files in walk(directory, False):
        for name in files:
            try_delete(try_overwrite(try_rename(root, name)))
        try_delete(try_rename(root))

def try_rename(root, name=None):
    "Try to rename a file or directory."
    if name is None:
        old, new = root, path.join(path.dirname(root), uuid4().hex)
    else:
        old, new = path.join(root, name), path.join(root, uuid4().hex)
    try:
        rename(old, new)
    except EnvironmentError:
        return old
    return new

def try_overwrite(filename):
    "Try to overwrite a file."
    try:
        size = path.getsize(filename)
        if size > 0:
            with open(filename, 'r+b', 0) as file:
                while size > 0:
                    size -= file.write(urandom(min(size, 1 << 20)))
    except EnvironmentError:
        pass
    return filename

def try_delete(file_or_dir):
    "Try to delete a file or directory."
    try:
        if path.isfile(file_or_dir):
            remove(file_or_dir)
        elif path.isdir(file_or_dir):
            rmdir(file_or_dir)
    except EnvironmentError:
        pass
    return file_or_dir

################################################################################

if __name__ == '__main__':
    main()