删除 python 上不为空的目录
Delete a directory that is not empty on python
所以,我需要清理一个不为空的目录。
我创建了以下 function.For 测试原因 我试图删除 JDK 安装
def clean_dir(location):
fileList = os.listdir(location)
for fileName in fileList:
fullpath=os.path.join(location, fileName)
if os.path.isfile(fullpath):
os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
os.remove(location + "/" + fileName)
elif os.path.isdir(fullpath):
if len(os.listdir(fullpath)) > 0:
clean_dir(fullpath)
#os.rmdir(location + "/" + fileName)
shutil.rmtree(location + "/" + fileName)
return
我尝试使用 rmtree 和 rmdir,但都失败了。
我在使用 rmtree 时遇到的错误是:
OSError: Cannot call rmtree on a symbolic link
这是我在使用 rmdir 时遇到的错误:
OSError: [Errno 66] Directory not empty:
'/tmp/jdk1.8.0_25/jre/lib/amd64/server'
代码在 windows 上运行正常。但由于某种原因,它在 linux.
上失败了
您遇到了 Windows 和 Linux(实际上是 UNIX)处理文件系统的方式之间的差异之一。我相信在您的代码中添加一个额外的案例至少会有所帮助:
...
for fileName in fileList:
fullpath = os.path.join(location, fileName)
## |<-- Handle symlink -->|
if os.path.islink(fullpath) or os.path.isfile(fullpath):
os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
os.remove(os.path.join(location, fileName))
elif os.path.isdir(fullpath):
if len(os.listdir(fullpath)) > 0:
clean_dir(fullpath)
#os.rmdir(os.path.join(location, fileName))
shutil.rmtree(os.path.join(location, fileName))
...
这应该可以正确处理条目是 symlink 的情况,并像删除文件一样删除它。我不确定 chmod
是否必要 - 它可能适用于 link 的目标,但以与文件相同的方式处理它应该不会有什么坏处。
但是,我只是检查 os.path.file
与符号 link returns 指向的 "thing" 的类型,因此需要额外检查区分 link 本身和指向的东西。同样为了便于携带,而不是附加“/”使用上面新编辑的 os.path.join
。
kronenpj 谢谢,就是这个主意。但是当你有一个符号链接时,它会像普通文件一样尝试删除,但失败了。我必须添加一个新的 elif 并为符号链接添加取消链接选项
def clean_dir(location):
fileList = os.listdir(location)
for fileName in fileList:
fullpath=os.path.join(location, fileName)
if os.path.isfile(fullpath):
os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
os.remove(os.path.join(location, fileName))
elif os.path.islink(fullpath):
os.unlink(fullpath)
elif os.path.isdir(fullpath):
if len(os.listdir(fullpath)) > 0:
clean_dir(fullpath)
#os.rmdir(location + "/" + fileName)
shutil.rmtree(os.path.join(location, fileName))
return
所以,我需要清理一个不为空的目录。 我创建了以下 function.For 测试原因 我试图删除 JDK 安装
def clean_dir(location):
fileList = os.listdir(location)
for fileName in fileList:
fullpath=os.path.join(location, fileName)
if os.path.isfile(fullpath):
os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
os.remove(location + "/" + fileName)
elif os.path.isdir(fullpath):
if len(os.listdir(fullpath)) > 0:
clean_dir(fullpath)
#os.rmdir(location + "/" + fileName)
shutil.rmtree(location + "/" + fileName)
return
我尝试使用 rmtree 和 rmdir,但都失败了。
我在使用 rmtree 时遇到的错误是:
OSError: Cannot call rmtree on a symbolic link
这是我在使用 rmdir 时遇到的错误:
OSError: [Errno 66] Directory not empty: '/tmp/jdk1.8.0_25/jre/lib/amd64/server'
代码在 windows 上运行正常。但由于某种原因,它在 linux.
上失败了您遇到了 Windows 和 Linux(实际上是 UNIX)处理文件系统的方式之间的差异之一。我相信在您的代码中添加一个额外的案例至少会有所帮助:
...
for fileName in fileList:
fullpath = os.path.join(location, fileName)
## |<-- Handle symlink -->|
if os.path.islink(fullpath) or os.path.isfile(fullpath):
os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
os.remove(os.path.join(location, fileName))
elif os.path.isdir(fullpath):
if len(os.listdir(fullpath)) > 0:
clean_dir(fullpath)
#os.rmdir(os.path.join(location, fileName))
shutil.rmtree(os.path.join(location, fileName))
...
这应该可以正确处理条目是 symlink 的情况,并像删除文件一样删除它。我不确定 chmod
是否必要 - 它可能适用于 link 的目标,但以与文件相同的方式处理它应该不会有什么坏处。
但是,我只是检查 os.path.file
与符号 link returns 指向的 "thing" 的类型,因此需要额外检查区分 link 本身和指向的东西。同样为了便于携带,而不是附加“/”使用上面新编辑的 os.path.join
。
kronenpj 谢谢,就是这个主意。但是当你有一个符号链接时,它会像普通文件一样尝试删除,但失败了。我必须添加一个新的 elif 并为符号链接添加取消链接选项
def clean_dir(location):
fileList = os.listdir(location)
for fileName in fileList:
fullpath=os.path.join(location, fileName)
if os.path.isfile(fullpath):
os.chmod(fullpath, stat.S_IRWXU | stat.S_IRWXG | stat.S_IRWXO)
os.remove(os.path.join(location, fileName))
elif os.path.islink(fullpath):
os.unlink(fullpath)
elif os.path.isdir(fullpath):
if len(os.listdir(fullpath)) > 0:
clean_dir(fullpath)
#os.rmdir(location + "/" + fileName)
shutil.rmtree(os.path.join(location, fileName))
return