用户登录
用户注册

分享至

递归删除目录和所有符号链接

  • 作者: 锄禾日当午汗滴禾下土谁知盘中餐吃醋
  • 来源: 51数据库
  • 2022-10-19

问题描述

我尝试使用shutil删除一个目录和所有包含的文件,如下所示:

import shutil
from os.path import exists
if exists(path_dir):
    shutil.rmtree(path_dir)

遗憾的是,我的解决方案不起作用,引发以下错误:

FileNotFoundError: [Errno 2] No such file or directory: '._image1.jpg'
快速搜索显示我有这个问题。 在我的理解中,rmtree函数等同于rm -Rf $DIR外壳命令--但情况似乎并非如此。

附注:用于重建目的。例如,请使用ln -s /path/to/original /path/to/link

创建符号链接

推荐答案

这很奇怪,在Windows 10和Ubuntu 20.04.2 LTS中,在要删除的文件夹下有或没有符号链接的Shutil.rmtree()都没有问题。

无论如何,请尝试以下代码。我在Windows10和Ubuntu上试用过。

from pathlib import Path
import shutil


def delete_dir_recursion(p):
    """
    Delete folder, sub-folders and files.
    """
    for f in p.glob('**/*'):
        if f.is_symlink():
            f.unlink(missing_ok=True)  # missing_ok is added in python 3.8
            print(f'symlink {f.name} from path {f} was deleted')
        elif f.is_file():
            f.unlink()
            print(f'file: {f.name} from path {f} was deleted')
        elif f.is_dir():
            try:
                f.rmdir()  # delete empty sub-folder
                print(f'folder: {f.name} from path {f} was deleted')
            except OSError:  # sub-folder is not empty
                delete_dir_recursion(f)  # recurse the current sub-folder
            except Exception as exception:  # capture other exception
                print(f'exception name: {exception.__class__.__name__}')
                print(f'exception msg: {exception}')

    try:
        p.rmdir()  # time to delete an empty folder
        print(f'folder: {p.name} from path {p} was deleted')
    except NotADirectoryError:
        p.unlink()  # delete folder even if it is a symlink, linux
        print(f'symlink folder: {p.name} from path {p} was deleted')
    except Exception as exception:
        print(f'exception name: {exception.__class__.__name__}')
        print(f'exception msg: {exception}')


def delete_dir(folder):
    p = Path(folder)

    if not p.exists():
        print(f'The path {p} does not exists!')
        return

    # Attempt to delete the whole folder at once.
    try:
        shutil.rmtree(p)
    except Exception as exception:
        print(f'exception name: {exception.__class__.__name__}')
        print(f'exception msg: {exception}')
        # continue parsing the folder
    else:  # else if no issues on rmtree()
        if not p.exists():  # verify
            print(f'folder {p} was successfully deleted by shutil.rmtree!')
            return

    print(f'Parse the folder {folder} ...')
    delete_dir_recursion(p)

    if not p.exists():  # verify
        print(f'folder {p} was successfully deleted!')

# start
folder_to_delete = '/home/zz/tmp/sample/b'  # delete folder b
delete_dir(folder_to_delete)

示例输出:

我们将删除该文件夹b。

.
├── 1.txt
├── a
├── b
│?? ├── 1
│?? ├── 1.txt -> ../1.txt
│?? ├── 2
│?? │?? └── 21
│?? │??     └── 21.txt
│?? ├── 3
│?? │?? └── 31
│?? ├── 4
│?? │?? └── c -> ../../c
│?? ├── a -> ../a
│?? └── b.txt
├── c

Parse the folder /home/zz/tmp/sample/b ...
symlink a from path /home/zz/tmp/sample/b/a was deleted
symlink c from path /home/zz/tmp/sample/b/4/c was deleted
folder: 4 from path /home/zz/tmp/sample/b/4 was deleted
symlink 1.txt from path /home/zz/tmp/sample/b/1.txt was deleted
file: b.txt from path /home/zz/tmp/sample/b/b.txt was deleted
file: 21.txt from path /home/zz/tmp/sample/b/2/21/21.txt was deleted
folder: 21 from path /home/zz/tmp/sample/b/2/21 was deleted
folder: 2 from path /home/zz/tmp/sample/b/2 was deleted
folder: 1 from path /home/zz/tmp/sample/b/1 was deleted
folder: 31 from path /home/zz/tmp/sample/b/3/31 was deleted
folder: 3 from path /home/zz/tmp/sample/b/3 was deleted
folder: b from path /home/zz/tmp/sample/b was deleted
folder /home/zz/tmp/sample/b was successfully deleted!
软件
前端设计
程序设计
Java相关