Skip to content Skip to sidebar Skip to footer

How To Erase The Contents Of A Directory That Contains Files, Directories, Links And Special Files At Its Root Which Must Not Be Deleted?

I need to empty a directory but save a few special files. The directory to be cleaned contains files, directories and symbolic links. How do I verify that I'm deleting the right

Solution 1:

I wrote some methods that fluff up my tmp folder with test material. The actual method I needed I called "directoryclean".

This ended up harder than I expected. os.remove cannot seem to handle symbolic links. os.removedirs raised some exceptions I did not understand.

#!/usr/bin/env python                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               

import os
import sys
import shutil
import random
import string
import itertools

def randomstring( stringlen ):
    return ''.join( random.choice( string.lowercase ) for _ in range( stringlen ) )

def flufffilemake( filename ):
    with file( filename, 'wt+' ) as f:
        for i in range( 10 ):
            f.write( randomstring( 1000 ) )

def fluffdirmake( root, maxdepth=5 ):
    if root.count( '/' ) <= maxdepth:
        for i in range( random.randint( 0, 5 ) ):
            dirname = os.path.join( root, randomstring( 4 ) )
            os.mkdir( dirname )
            fluffdirmake( dirname )
            for i in range( random.randint( 0, 10 ) ):
                flufffilemake( os.path.join( dirname, randomstring( 5 ) ) )

def fluffsymlinksmake( top, sympath ):
    for root, dirs, files in os.walk(top):
        for name in files:
            if random.randint( 0, 3 ) == 0:
                randomname = randomstring( 6 )
                symlinktarget = os.path.join( sympath, randomname )
                flufffilemake( symlinktarget )
                os.symlink( symlinktarget, os.path.join( root, randomname ) )
        for name in dirs:
            if random.randint( 0, 3 ) == 0:
                randomname = randomstring( 6 )
                symlinktarget = os.path.join( sympath, randomname )
                os.makedirs( symlinktarget )
                os.symlink( symlinktarget, os.path.join( root, randomname ) )


def directoryclean( top, specialfiles ):
    for root, dirs, files in os.walk( top, topdown=False ):
        for df in itertools.chain( dirs, files ):
            p = os.path.join( root, df )
            if not df in specialfiles:
                try:
                    os.unlink( p ) # this works for both links to files and links to directories and also plain files
                except OSError:
                    shutil.rmtree( os.path.join( root, df ), ignore_errors=True )


if __name__ == '__main__':
    root        = '/tmp/dirdel'
    sym         = '/tmp/sym'
    try:
        os.makedirs( root )
        os.makedirs( sym )
    except:
        pass

    specialfiles = [ 'specialfile%d' % i for i in range( random.randint( 0, 5 ) ) ]
    for f in specialfiles:
        with file( os.path.join( root, f ), 'wt' ) as f:
            f.write( '   ' )

    fluffdirmake( root )
    fluffsymlinksmake( root, sym )
    for f in specialfiles:
        flufffilemake( os.path.join( root, f ) )

    sys.stdin.read( 1 ) # wait for keypress so I can manually inspect the created files
    directoryclean( root, specialfiles )

    for f in specialfiles:
        assert os.path.exists( os.path.join( root, f ) )
    remainingfiles = os.listdir( root )
    assert len( remainingfiles ) == len( specialfiles )

Post a Comment for "How To Erase The Contents Of A Directory That Contains Files, Directories, Links And Special Files At Its Root Which Must Not Be Deleted?"