- Python : How to delete a directory recursively using shutil.rmtree()
- How to delete a directory recursively using shutil.rmtree() in Python ?
- Delete an empty directory using os.rmdir() :
- Delete all files in a directory & sub-directories recursively using shutil.rmtree() :
- shutil.rmtree() & ignore_errors :
- Passing callbacks in shutil.rmtree() with onerror :
- Python : How to delete a directory recursively using shutil.rmtree()
- Delete an empty directory using os.rmdir()
- Frequently Asked:
- Delete all files in a directory & sub-directories recursively using shutil.rmtree()
- shutil.rmtree() & ignore_errors
- Passing callbacks in shutil.rmtree() with onerror
- Related posts:
Python : How to delete a directory recursively using shutil.rmtree()
How to delete a directory recursively using shutil.rmtree() in Python ?
In this article, we will discuss about how we can delete an empty directory and also all contents of a directory including sub directories using shutil.rmtree().
Delete an empty directory using os.rmdir() :
The os module of python provide a function i.e. os.rmdir(pathOfDir) which can delete an empty directory. It can also give rise to certain errors in some scenarios like:
- When directory is not empty : OSError: [WinError 145] The directory is not empty:
- When the given path not pointing to any of the directory : NotADirectoryError: [WinError 267] The directory name is invalid:
- When the given path has no directory : FileNotFoundError: [WinError 2] The system cannot find the file specified:
#Program : import os # Deleting a empty directory using function os.rmdir() and handle the exceptions try: os.rmdir('/somedirec/log2') except: print('Not found directory')
Output : Not found directory
Delete all files in a directory & sub-directories recursively using shutil.rmtree() :
The shutil module of python provides a function i.e. shutil.rmtree() to delete all the contents present in a directory.
Syntax : shutil.rmtree(path, ignore_errors=False, onerror=None)
import shutil dirPath = '/somedirec/logs5/'; # trying to delete all contents of a directory and handle exceptions try: shutil.rmtree(dirPath) except: print('Not found directory')
Output : Not found directory
Here in this case if found, all contents of directory ‘/somedir/logs/’ will be deleted. If any of the files in directory has read only attributes then user can’t delete the file and exception i.e. PermissionError will be raised therefore we can’t delete any remaining required files.
shutil.rmtree() & ignore_errors :
In previous scenario if we failed to delete any file, then we can’t delete further required files in the directory. Now, we can ignore the errors by passing ignore_errors=True in shutil.rmtree() .
It will skip the file which raised the exception and then going forward it can delete all of the remaining files.
Let there be a scenario where we can’t delete a file in log directory, then we can use the following syntax so that this exception can be ignored:
shutil.rmtree(dirPath, ignore_errors=True)
Passing callbacks in shutil.rmtree() with onerror :
Instead of ignoring errors, there may be a case where we have to handle the errors.
Syntax : shutil.rmtree(path, ignore_errors=False, onerror=None)
In onerror parameter, callback function can be called to handle the errors
shutil.rmtree(dirPath, onerror=handleError)
The callable function passed must be callable like:
def handleError(func, path, exc_info): pass
- function : It is the function which raised exception.
- path : The path that passed which raises the exception while removal.
- excinfo : The exception information is returned
Now, if any exception is raised while deleting a file, then callback will handle the error. Then, shutil.rmtree() can continue deleting remaining files.
Now let a case where we want to delete all the contents of a directory ‘/somediec/logs’ , and there is somewhere a file in logs directory which shows permission issues, and we can’t delete all. So callback will be passed in oneerror parameter of that file.
In the callback if it accesses issue, then we will change the file permission and then call calling function i.e. rmtree() with path of file. Then the file will be deleted and rmtree() will further delete remaining contents in the directory.
import os import shutil import stat #Error handling function will try to change permission and call calling function again def handleError(func, path, exc_info): print('Handling Error for file ' , path) print(exc_info) # check that if the file is accessing the issue if not os.access(path, os.W_OK): print('helloWorld') # trying to change the permission of file os.chmod(path, stat.S_IWUSR) # Tring to call the calling function again func(path)
Python : How to delete a directory recursively using shutil.rmtree()
In this article we will discuss how to delete an empty directory and also all contents of directory recursively i.e including contents of its sub directories.
Delete an empty directory using os.rmdir()
Python’s os module provide a function to delete an empty directory i.e.
Path of directory can be relative or absolute. It will delete the empty folder at given path.
It can also raise errors in following scenarios,
- If directory is not empty then it will cause OSError i.e.
- OSError: [WinError 145] The directory is not empty:
- NotADirectoryError: [WinError 267] The directory name is invalid:
- FileNotFoundError: [WinError 2] The system cannot find the file specified:
Let’s use this to delete an empty directory,
Frequently Asked:
import os # Delete an empty directory using os.rmdir() and handle exceptions try: os.rmdir('/somedir/log9') except: print('Error while deleting directory')
Delete all files in a directory & sub-directories recursively using shutil.rmtree()
Python’s shutil module provides a function to delete all the contents of a directory i.e.
shutil.rmtree(path, ignore_errors=False, onerror=None)
It accepts 3 arguments ignore_errors, onerror and path.
path argument should be a path of the directory to be deleted. We we will discuss other arguments very soon.
Let’s use this to delete all the contents of a directory i.e.
import shutil dirPath = '/somedir/logs/'; # Delete all contents of a directory using shutil.rmtree() and handle exceptions try: shutil.rmtree(dirPath) except: print('Error while deleting directory')
It will delete all the contents of directory’/somedir/logs/’
But if any of the file in directory has read only attributes i.e. user can not delete that file, then it will raise an exception i.e.
PermissionError: [WinError 5] Access is denied:Also it will not delete the remaining files. To handle this kind of scenario let’s use other argument ignore_errors.
shutil.rmtree() & ignore_errors
by passing ignore_errors=True in shultil.rmtree() we can ignore the errors encountered. It will go forward with deleting all the files and skip the files which raise exceptions while deleting.
Suppose we have a file in log directory that can not be deleted due to permission issues. So,
shutil.rmtree(dirPath, ignore_errors=True)
will remove all the other files from ‘/somedir/logs’ directory except the file with permission issues. Also, it will not raise any error.
But this might not be the case always, we might want to handle errors instead of ignoring them. For that we have other argument of shutil.rmtree() i.e. onerror.
Passing callbacks in shutil.rmtree() with onerror
shutil.rmtree(path, ignore_errors=False, onerror=None)
In onerror parameter we can pass a callback function to handle errors i.e.
shutil.rmtree(dirPath, onerror=handleError )
callback function passed in onerror must be a callable like this,
def handleError(func, path, exc_info): pass
It should accepts three parameters:
- function
- function which raised the exception
- path name passed which raised the exception while removal
- exception information returned by sys.exc_info()
If any exception occurs while deleting a file in rmtree() and onerror callback is provided. Then callback will be called to handle the error. Afterwards shutil.rmtree() will continue deleting other files.
Now suppose we want to delete all the contents of directory ‘/somedir/logs’ . But we have a file in logs directory that can not be deleted due to permission issues. Let’s pass a callback to handle the error
import os import shutil ''' Error handler function It will try to change file permission and call the calling function again, ''' def handleError(func, path, exc_info): print('Handling Error for file ' , path) print(exc_info) # Check if file access issue if not os.access(path, os.W_OK): print('Hello') # Try to change the permision of file os.chmod(path, stat.S_IWUSR) # call the calling function again func(path)
# Delete all contents of a directory and handle errors shutil.rmtree(dirPath, onerror=handleError )
Now while deleting all the files in given directory, as soon as rmtree() encounters a file that can not be deleted, it calls the callback passed in onerror parameter for that file.
In this callback we will check if it’s am access issue then we will change the file permission and then call called function func i.e. rmtree() with the path of file. t will eventually delete the file. Then rmtree() will continue deleting other files in the directory.Complete example is as follows,
import os import shutil import stat ''' Error handler function It will try to change file permission and call the calling function again, ''' def handleError(func, path, exc_info): print('Handling Error for file ' , path) print(exc_info) # Check if file access issue if not os.access(path, os.W_OK): print('Hello') # Try to change the permision of file os.chmod(path, stat.S_IWUSR) # call the calling function again func(path) def main(): print("******** Delete an empty directory *********") # Delete an empty directory using os.rmdir() and handle exceptions try: os.rmdir('/somedir/log9') except: print('Error while deleting directory') print("******** Delete all contents of a directory *********") dirPath = '/somedir/logs/'; # Delete all contents of a directory using shutil.rmtree() and handle exceptions try: shutil.rmtree(dirPath) except: print('Error while deleting directory') # Delete all contents of a directory and ignore errors shutil.rmtree(dirPath, ignore_errors=True) # Delete all contents of a directory and handle errors shutil.rmtree(dirPath, onerror=handleError ) if __name__ == '__main__': main()
Related posts: