shutil — 高级文件操作

源代码: Lib/shutil.py


shutil 模块提供了许多关于文件和文件集合的高级操作。特别是,提供了支持文件复制和删除的函数。有关对单个文件的操作,另请参阅 os 模块。

警告

即使是更高级的文件复制函数 (shutil.copy(), shutil.copy2()) 也无法复制所有文件元数据。

在 POSIX 平台上,这意味着文件所有者和组以及 ACL 会丢失。在 Mac OS 上,资源 fork 和其他元数据不会被使用。这意味着资源将会丢失,并且文件类型和创建者代码将不正确。在 Windows 上,文件所有者、ACL 和备用数据流不会被复制。

目录和文件操作

shutil.copyfileobj(fsrc, fdst[, length])

类文件对象 fsrc 的内容复制到类文件对象 fdst。如果给定整数 length,则它是缓冲区大小。特别是,负数 length 值表示在不循环遍历源数据块的情况下复制数据;默认情况下,数据以块的形式读取,以避免不受控制的内存消耗。请注意,如果 fsrc 对象的当前文件位置不是 0,则只会复制从当前文件位置到文件末尾的内容。

shutil.copyfile(src, dst, *, follow_symlinks=True)

将名为 src 的文件的内容(无元数据)复制到名为 dst 的文件,并以尽可能高效的方式返回 dstsrcdst路径类对象或以字符串形式给出的路径名。

dst 必须是完整的目标文件名;请查看 copy(),它接受目标目录路径进行复制。如果 srcdst 指定相同的文件,则会引发 SameFileError

目标位置必须可写;否则,将引发 OSError 异常。如果 dst 已经存在,它将被替换。不能使用此函数复制字符或块设备和管道等特殊文件。

如果 follow_symlinks 为 false 且 src 是符号链接,则将创建一个新的符号链接,而不是复制 src 指向的文件。

引发带有参数 srcdst审计事件 shutil.copyfile

在 3.3 版本中更改: 以前引发 IOError 而不是 OSError。添加了 follow_symlinks 参数。现在返回 dst

在 3.4 版本中更改: 引发 SameFileError 而不是 Error。由于前者是后者的子类,因此此更改向后兼容。

在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。

exception shutil.SameFileError

如果 copyfile() 中的源和目标是同一文件,则会引发此异常。

在 3.4 版本中添加。

shutil.copymode(src, dst, *, follow_symlinks=True)

将权限位从 src 复制到 dst。文件内容、所有者和组不受影响。srcdst路径类对象或以字符串形式给出的路径名。如果 follow_symlinks 为 false,并且 srcdst 都是符号链接,则 copymode() 将尝试修改 dst 本身的模式(而不是它指向的文件)。并非每个平台都提供此功能;有关详细信息,请参阅 copystat()。如果 copymode() 无法在本地平台上修改符号链接,并且要求这样做,它将不执行任何操作并返回。

引发带有参数 srcdst审计事件 shutil.copymode

在 3.3 版本中更改: 添加了 follow_symlinks 参数。

shutil.copystat(src, dst, *, follow_symlinks=True)

将权限位、上次访问时间、上次修改时间和标志从 src 复制到 dst。在 Linux 上,如果可能,copystat() 还会复制“扩展属性”。文件内容、所有者和组不受影响。srcdst路径类对象或以字符串形式给出的路径名。

如果 follow_symlinks 为 false,并且 srcdst 都指向符号链接,则 copystat() 将对符号链接本身进行操作,而不是符号链接引用的文件,从 src 符号链接读取信息,并将信息写入 dst 符号链接。

注意

并非所有平台都提供检查和修改符号链接的功能。Python 本身可以告诉您本地有哪些功能可用。

  • 如果 os.chmod in os.supports_follow_symlinksTrue,则 copystat() 可以修改符号链接的权限位。

  • 如果 os.utime in os.supports_follow_symlinksTrue,则 copystat() 可以修改符号链接的上次访问时间和修改时间。

  • 如果 os.chflags in os.supports_follow_symlinksTruecopystat() 可以修改符号链接的标志。(os.chflags 并非在所有平台上都可用。)

在部分或全部功能不可用的平台上,当要求修改符号链接时,copystat() 将会复制它可以复制的所有内容。copystat() 永远不会返回失败。

请参阅 os.supports_follow_symlinks 获取更多信息。

引发一个 审计事件 shutil.copystat,参数为 src, dst

3.3 版本更改: 添加了 follow_symlinks 参数,并支持 Linux 扩展属性。

shutil.copy(src, dst, *, follow_symlinks=True)

将文件 src 复制到文件或目录 dstsrcdst 应该是 路径类对象 或字符串。 如果 dst 指定一个目录,文件将会被复制到 dst 中,并使用 src 的基本文件名。 如果 dst 指定一个已经存在的文件,它将被替换。 返回新创建文件的路径。

如果 follow_symlinks 为 false,且 src 是一个符号链接,那么 dst 将被创建为一个符号链接。 如果 follow_symlinks 为 true 且 src 是一个符号链接,那么 dst 将会是 src 指向的文件的副本。

copy() 复制文件数据和文件的权限模式(请参阅 os.chmod())。其他元数据,如文件的创建和修改时间,不会被保留。要保留原始文件的所有元数据,请改用 copy2()

引发带有参数 srcdst审计事件 shutil.copyfile

引发带有参数 srcdst审计事件 shutil.copymode

3.3 版本更改: 添加了 follow_symlinks 参数。现在返回新创建的文件的路径。

在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。

shutil.copy2(src, dst, *, follow_symlinks=True)

copy() 相同,除了 copy2() 还会尝试保留文件元数据。

follow_symlinks 为 false,且 src 是一个符号链接时,copy2() 会尝试将所有元数据从 src 符号链接复制到新创建的 dst 符号链接。 然而,此功能并非在所有平台上都可用。 在部分或全部功能不可用的平台上,copy2() 将会保留它可以保留的所有元数据; copy2() 永远不会因为无法保留文件元数据而引发异常。

copy2() 使用 copystat() 来复制文件元数据。 请参阅 copystat() 获取有关修改符号链接元数据的平台支持的更多信息。

引发带有参数 srcdst审计事件 shutil.copyfile

引发一个 审计事件 shutil.copystat,参数为 src, dst

3.3 版本更改: 添加了 follow_symlinks 参数,尝试复制扩展文件系统属性(目前仅限 Linux)。现在返回新创建的文件的路径。

在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。

shutil.ignore_patterns(*patterns)

这个工厂函数创建一个函数,该函数可以用作 copytree()ignore 参数的可调用对象,忽略与提供的 glob 风格 patterns 之一匹配的文件和目录。请参阅下面的示例。

shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False, dirs_exist_ok=False)

将根目录为 src 的整个目录树递归地复制到名为 dst 的目录,并返回目标目录。默认情况下,也将创建包含 dst 所需的所有中间目录。

目录的权限和时间使用 copystat() 复制,单个文件使用 copy2() 复制。

如果 symlinks 为 true,则源树中的符号链接在新树中表示为符号链接,并且原始链接的元数据将在平台允许的范围内进行复制;如果为 false 或省略,则将链接文件的内容和元数据复制到新树中。

symlinks 为 false 时,如果符号链接指向的文件不存在,则会在复制过程结束时在 Error 异常中引发的错误列表中添加一个异常。如果您想忽略此异常,可以将可选的 ignore_dangling_symlinks 标志设置为 true。请注意,此选项在不支持 os.symlink() 的平台上无效。

如果给定 ignore,则它必须是可调用对象,它将接收 copytree() 正在访问的目录及其内容的列表作为其参数,如 os.listdir() 返回的那样。由于 copytree() 是递归调用的,因此对于复制的每个目录,ignore 可调用对象将调用一次。该可调用对象必须返回相对于当前目录的目录和文件名序列(即其第二个参数中的项目子集);然后在复制过程中将忽略这些名称。ignore_patterns() 可用于创建基于 glob 风格模式忽略名称的此类可调用对象。

如果发生异常,则会引发一个 Error,其中包含一个原因列表。

如果给定 copy_function,则它必须是一个可调用对象,该对象将用于复制每个文件。它将使用源路径和目标路径作为参数调用。默认情况下,使用 copy2(),但可以使用任何支持相同签名的函数(如 copy())。

如果 dirs_exist_ok 为 false(默认值)并且 dst 已经存在,则会引发 FileExistsError。如果 dirs_exist_ok 为 true,则复制操作将在遇到现有目录时继续,并且 dst 树中的文件将被 src 树中的相应文件覆盖。

引发一个 审计事件 shutil.copytree,参数为 srcdst

3.2 版本更改: 添加了 copy_function 参数,以便能够提供自定义的复制函数。添加了 ignore_dangling_symlinks 参数,以便在 symlinks 为 false 时忽略悬挂的符号链接错误。

3.3 版本更改: symlinks 为 false 时,复制元数据。现在返回 dst

在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。

3.8 版本更改: 添加了 dirs_exist_ok 参数。

shutil.rmtree(path, ignore_errors=False, onerror=None, *, onexc=None, dir_fd=None)

删除整个目录树;path 必须指向一个目录(但不能是指向目录的符号链接)。如果 ignore_errors 为 True,则会忽略因删除失败而产生的错误;如果为 False 或省略,则此类错误将通过调用由 onexconerror 指定的处理程序进行处理,或者如果两者都省略,则会将异常传播给调用方。

此函数可以支持相对于目录描述符的路径

注意

在支持必要的文件描述符 (fd) 功能的平台上,默认使用 rmtree() 的防符号链接攻击版本。在其他平台上,rmtree() 的实现容易受到符号链接攻击:在适当的时机和情况下,攻击者可以操纵文件系统上的符号链接来删除他们原本无法访问的文件。应用程序可以使用 rmtree.avoids_symlink_attacks 函数属性来确定适用哪种情况。

如果提供了 onexc,它必须是一个可调用对象,接受三个参数:functionpathexcinfo

第一个参数 function 是引发异常的函数;它取决于平台和实现。第二个参数 path 将是传递给 function 的路径名称。第三个参数 excinfo 是引发的异常。由 onexc 引发的异常将不会被捕获。

已弃用的 onerror 类似于 onexc,不同之处在于它接收的第三个参数是从 sys.exc_info() 返回的元组。

引发一个带有参数 pathdir_fd审计事件 shutil.rmtree

在 3.3 版本中更改: 添加了一个防符号链接攻击的版本,如果平台支持基于文件描述符的功能,则会自动使用。

在 3.8 版本中更改: 在 Windows 上,将不再删除目录连接的内容,然后再删除该连接。

在 3.11 版本中更改: 添加了 dir_fd 参数。

在 3.12 版本中更改: 添加了 onexc 参数,弃用了 onerror

在 3.13 版本中更改: rmtree() 现在会忽略除了顶层路径之外的所有路径的 FileNotFoundError 异常。除了 OSErrorOSError 子类的异常外,现在始终将其他异常传播给调用方。

指示当前平台和实现是否提供了 rmtree() 的防符号链接攻击版本。目前,这仅适用于支持基于文件描述符的目录访问功能的平台。

3.3 版本中新增。

shutil.move(src, dst, copy_function=copy2)

递归地将文件或目录 (src) 移动到另一个位置并返回目标。

如果 dst 是一个现有目录或指向目录的符号链接,则 src 将被移动到该目录内部。该目录中的目标路径必须不存在。

如果 dst 已经存在但不是目录,则可能会根据 os.rename() 的语义覆盖它。

如果目标位于当前文件系统上,则使用 os.rename()。否则,使用 copy_functionsrc 复制到目标,然后删除 src。对于符号链接,将创建一个新的符号链接指向 src 的目标作为目标,并且将删除 src

如果给定了 copy_function,它必须是一个可调用对象,接受两个参数,src 和目标,并且如果不能使用 os.rename(),则将使用它将 src 复制到目标。如果源是一个目录,则会调用 copytree(),并传递给它 copy_function。默认的 copy_functioncopy2()。将 copy() 用作 copy_function 可以在无法复制元数据的情况下允许移动成功,但代价是不复制任何元数据。

引发一个带有参数 srcdst审计事件 shutil.move

在 3.3 版本中更改: 为外部文件系统添加了显式的符号链接处理,从而使其适应 GNU 的 mv 的行为。现在返回 dst

在 3.5 版本中更改: 添加了 copy_function 关键字参数。

在 3.8 版本中更改: 内部可以使用特定于平台的快速复制系统调用,以便更有效地复制文件。请参阅 平台相关的快速复制操作 部分。

在 3.9 版本中更改: 接受 srcdst路径类对象

shutil.disk_usage(path)

具名元组的形式返回有关给定路径的磁盘使用情况统计信息,该具名元组具有属性 totalusedfree,它们分别是总空间、已用空间和可用空间的大小(以字节为单位)。path 可以是文件或目录。

注意

在 Unix 文件系统上,path 必须指向 **已挂载** 文件系统分区中的路径。在这些平台上,CPython 不会尝试从非挂载的文件系统中检索磁盘使用信息。

3.3 版本中新增。

在 3.8 版本中更改: 在 Windows 上,path 现在可以是文件或目录。

可用性: Unix,Windows。

shutil.chown(path, user=None, group=None, *, dir_fd=None, follow_symlinks=True)

更改给定 path 的所有者 user 和/或 group

user 可以是系统用户名或 uid;group 也是如此。至少需要一个参数。

另请参阅底层函数 os.chown()

引发一个带有参数 pathusergroup审计事件 shutil.chown

可用性: Unix。

3.3 版本中新增。

3.13 版本更改: 添加了 dir_fdfollow_symlinks 参数。

shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)

返回如果调用给定的 cmd 将要运行的可执行文件的路径。如果不会调用任何 cmd,则返回 None

mode 是一个传递给 os.access() 的权限掩码,默认情况下确定文件是否存在以及是否可执行。

path 是一个 “PATH 字符串”,指定要查找的目录,以 os.pathsep 分隔。当没有指定 path 时,PATH 环境变量将从 os.environ 读取,如果未设置,则回退到 os.defpath

在 Windows 上,如果 mode 不包括 os.X_OK,则当前目录会添加到 path 的前面。当 mode 包括 os.X_OK 时,将查询 Windows API NeedCurrentDirectoryForExePathW 以确定是否应将当前目录添加到 path 的前面。要避免为可执行文件查询当前工作目录:设置环境变量 NoDefaultCurrentDirectoryInExePath

同样在 Windows 上,PATHEXT 环境变量用于解析可能尚未包含扩展名的命令。例如,如果您调用 shutil.which("python")which() 将搜索 PATHEXT 以知道它应该在 path 目录中查找 python.exe。例如,在 Windows 上

>>> shutil.which("python")
'C:\\Python33\\python.EXE'

cmd 是包含目录组件的路径时,也会应用此规则。

>> shutil.which("C:\\Python33\\python")
'C:\\Python33\\python.EXE'

3.3 版本中新增。

3.8 版本更改: 现在接受 bytes 类型。如果 cmd 类型是 bytes,则结果类型也是 bytes

3.12 版本更改: 在 Windows 上,如果 mode 包括 os.X_OK 并且 WinAPI NeedCurrentDirectoryForExePathW(cmd) 为 false,则不再将当前目录添加到搜索路径的前面,否则即使当前目录已在搜索路径中也会添加到前面;即使 cmd 包括目录组件或以 PATHEXT 中的扩展名结尾,现在也使用 PATHEXT;并且现在可以找到没有扩展名的文件名。

exception shutil.Error

此异常收集在多文件操作期间引发的异常。对于 copytree(),异常参数是 3 元组 (srcname, dstname, exception) 的列表。

平台相关的有效复制操作

从 Python 3.8 开始,所有涉及文件复制的函数(copyfile()copy()copy2()copytree()move())可能会使用平台特定的“快速复制”系统调用,以便更有效地复制文件(请参阅 bpo-33671)。“快速复制”意味着复制操作发生在内核中,避免像 “outfd.write(infd.read())” 那样在 Python 中使用用户空间缓冲区。

在 macOS 上,fcopyfile 用于复制文件内容(而不是元数据)。

在 Linux 上,使用 os.sendfile()

在 Windows 上,shutil.copyfile() 使用更大的默认缓冲区大小(1 MiB 而不是 64 KiB)和基于 memoryview()shutil.copyfileobj() 变体。

如果快速复制操作失败并且未在目标文件中写入任何数据,则 shutil 将在内部静默回退到使用效率较低的 copyfileobj() 函数。

3.8 版本更改。

copytree 示例

一个使用 ignore_patterns() 助手的示例

from shutil import copytree, ignore_patterns

copytree(source, destination, ignore=ignore_patterns('*.pyc', 'tmp*'))

这将复制除 .pyc 文件和名称以 tmp 开头的文件或目录之外的所有内容。

另一个使用 ignore 参数添加日志调用的示例

from shutil import copytree
import logging

def _logpath(path, names):
    logging.info('Working in %s', path)
    return []   # nothing will be ignored

copytree(source, destination, ignore=_logpath)

rmtree 示例

此示例显示如何在 Windows 上删除目录树,其中某些文件设置了只读位。它使用 onexc 回调来清除只读位并重新尝试删除。任何后续失败都将传播。

import os, stat
import shutil

def remove_readonly(func, path, _):
    "Clear the readonly bit and reattempt the removal"
    os.chmod(path, stat.S_IWRITE)
    func(path)

shutil.rmtree(directory, onexc=remove_readonly)

存档操作

3.2 版本新增。

3.5 版本更改: 添加了对 xztar 格式的支持。

还提供了用于创建和读取压缩和存档文件的高级实用程序。它们依赖于 zipfiletarfile 模块。

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[, owner[, group[, logger]]]]]]])

创建一个存档文件(例如 zip 或 tar)并返回其名称。

base_name 是要创建的文件名,包括路径,减去任何特定于格式的扩展名。

format 是存档格式: “zip” (如果 zlib 模块可用)、“tar”、“gztar”(如果 zlib 模块可用)、“bztar”(如果 bz2 模块可用)或 “xztar”(如果 lzma 模块可用)。

root_dir 是将作为存档根目录的目录,存档中的所有路径都将相对于它;例如,我们通常在创建存档之前 chdir 到 root_dir 中。

base_dir 是我们开始存档的目录;即 base_dir 将是存档中所有文件和目录的公共前缀。必须相对于 root_dir 给出 base_dir。请参阅 使用 base_dir 的存档示例,了解如何一起使用 base_dirroot_dir

root_dirbase_dir 均默认为当前目录。

如果 dry_run 为 true,则不会创建任何存档,但会将要执行的操作记录到 logger 中。

创建 tar 存档时使用 ownergroup。默认情况下,使用当前所有者和组。

logger 必须是与 PEP 282 兼容的对象,通常是 logging.Logger 的实例。

verbose 参数未使用且已弃用。

引发一个 审计事件 shutil.make_archive,其参数为 base_nameformatroot_dirbase_dir

注意

当使用 register_archive_format() 注册的自定义归档器不支持 root_dir 参数时,此函数不是线程安全的。在这种情况下,它会临时将进程的当前工作目录更改为 root_dir 以执行归档。

在 3.8 版本中更改: 对于使用 format="tar" 创建的归档文件,现在使用现代 pax (POSIX.1-2001) 格式,而不是传统的 GNU 格式。

在 3.10.6 版本中更改: 此函数在创建标准 .zip 和 tar 归档文件时现在是线程安全的。

shutil.get_archive_formats()

返回支持的归档格式列表。 返回的序列中的每个元素都是一个元组 (name, description)

默认情况下,shutil 提供以下格式:

  • zip:ZIP 文件(如果 zlib 模块可用)。

  • tar:未压缩的 tar 文件。 新的归档文件使用 POSIX.1-2001 pax 格式。

  • gztar:gzip 压缩的 tar 文件(如果 zlib 模块可用)。

  • bztar:bzip2 压缩的 tar 文件(如果 bz2 模块可用)。

  • xztar:xz 压缩的 tar 文件(如果 lzma 模块可用)。

您可以使用 register_archive_format() 注册新格式或为任何现有格式提供自己的归档器。

shutil.register_archive_format(name, function[, extra_args[, description]])

为格式 name 注册一个归档器。

function 是将用于解包归档文件的可调用对象。 可调用对象将接收要创建的文件的 base_name,后跟开始归档的 base_dir (默认为 os.curdir)。 其他参数将作为关键字参数传递:ownergroupdry_runlogger(如在 make_archive() 中传递的)。

如果 function 具有设置为 True 的自定义属性 function.supports_root_dir,则 root_dir 参数将作为关键字参数传递。 否则,在调用 function 之前,进程的当前工作目录将临时更改为 root_dir。 在这种情况下,make_archive() 不是线程安全的。

如果给定,extra_args(name, value) 对的序列,当使用归档器可调用对象时,将用作额外的关键字参数。

descriptionget_archive_formats() 使用,该函数返回归档器的列表。 默认为空字符串。

在 3.12 版本中更改: 添加了对支持 root_dir 参数的函数的支持。

shutil.unregister_archive_format(name)

从支持的格式列表中删除归档格式 name

shutil.unpack_archive(filename[, extract_dir[, format[, filter]]])

解包一个归档文件。 filename 是归档文件的完整路径。

extract_dir 是解包归档文件的目标目录的名称。 如果未提供,则使用当前工作目录。

format 是归档格式:“zip”、“tar”、“gztar”、“bztar” 或 “xztar” 之一。 或使用 register_unpack_format() 注册的任何其他格式。 如果未提供,unpack_archive() 将使用归档文件名扩展名,并查看是否为该扩展名注册了解包器。 如果未找到,则会引发 ValueError

仅限关键字的 filter 参数将传递给底层解包函数。 对于 zip 文件,不接受 filter。 对于 tar 文件,建议将其设置为 'data',除非使用特定于 tar 和类 UNIX 文件系统的功能。(有关详细信息,请参阅 提取过滤器。) 'data' 过滤器将在 Python 3.14 中成为 tar 文件的默认值。

引发一个 审计事件 shutil.unpack_archive,其参数为 filenameextract_dirformat

警告

切勿在未事先检查的情况下从不受信任的来源提取归档文件。 文件可能会在 extract_dir 参数中指定的路径之外创建,例如,具有以 “/” 开头的绝对文件名或具有两个点 “..” 的成员。

在 3.7 版本中更改: 接受 filenameextract_dir路径类对象

在 3.12 版本中更改: 添加了 filter 参数。

shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])

注册一个解包格式。 name 是格式的名称,extensions 是与格式对应的扩展名列表,例如 Zip 文件的 .zip

function 是将用于解包归档文件的可调用对象。 可调用对象将接收

  • 归档文件的路径,作为位置参数;

  • 必须提取归档文件的目录,作为位置参数;

  • 如果将其提供给 unpack_archive(),则可能有一个 filter 关键字参数;

  • 额外的关键字参数,由 extra_args 指定,为 (名称, 值) 元组的序列。

可以提供 description 来描述格式,并且将由 get_unpack_formats() 函数返回。

shutil.unregister_unpack_format(name)

取消注册一个解包格式。name 是格式的名称。

shutil.get_unpack_formats()

返回所有已注册的解包格式的列表。返回的序列的每个元素都是一个元组 (name, extensions, description)

默认情况下,shutil 提供以下格式:

  • zip:ZIP 文件(仅当相应的模块可用时,解压压缩文件才有效)。

  • tar:未压缩的 tar 文件。

  • gztar:gzip 压缩的 tar 文件(如果 zlib 模块可用)。

  • bztar:bzip2 压缩的 tar 文件(如果 bz2 模块可用)。

  • xztar:xz 压缩的 tar 文件(如果 lzma 模块可用)。

您可以使用 register_unpack_format() 注册新格式或为您已有的任何格式提供自己的解包器。

归档示例

在此示例中,我们创建一个 gzip 压缩的 tar 文件,其中包含用户 .ssh 目录中的所有文件

>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> root_dir = os.path.expanduser(os.path.join('~', '.ssh'))
>>> make_archive(archive_name, 'gztar', root_dir)
'/Users/tarek/myarchive.tar.gz'

生成的归档文件包含

$ tar -tzvf /Users/tarek/myarchive.tar.gz
drwx------ tarek/staff       0 2010-02-01 16:23:40 ./
-rw-r--r-- tarek/staff     609 2008-06-09 13:26:54 ./authorized_keys
-rwxr-xr-x tarek/staff      65 2008-06-09 13:26:54 ./config
-rwx------ tarek/staff     668 2008-06-09 13:26:54 ./id_dsa
-rwxr-xr-x tarek/staff     609 2008-06-09 13:26:54 ./id_dsa.pub
-rw------- tarek/staff    1675 2008-06-09 13:26:54 ./id_rsa
-rw-r--r-- tarek/staff     397 2008-06-09 13:26:54 ./id_rsa.pub
-rw-r--r-- tarek/staff   37192 2010-02-06 18:23:10 ./known_hosts

使用 base_dir 的归档示例

在此示例中,与上面的示例类似,我们展示如何使用 make_archive(),但这次使用了 base_dir。我们现在有以下目录结构

$ tree tmp
tmp
└── root
    └── structure
        ├── content
            └── please_add.txt
        └── do_not_add.txt

在最终的归档文件中,应该包含 please_add.txt,但不应包含 do_not_add.txt。因此我们使用以下代码

>>> from shutil import make_archive
>>> import os
>>> archive_name = os.path.expanduser(os.path.join('~', 'myarchive'))
>>> make_archive(
...     archive_name,
...     'tar',
...     root_dir='tmp/root',
...     base_dir='structure/content',
... )
'/Users/tarek/my_archive.tar'

列出生成的归档文件中的文件,得到以下结果

$ python -m tarfile -l /Users/tarek/myarchive.tar
structure/content/
structure/content/please_add.txt

查询输出终端的大小

shutil.get_terminal_size(fallback=(columns, lines))

获取终端窗口的大小。

对于两个维度中的每一个,都会检查环境变量 COLUMNSLINES。如果变量已定义且值为正整数,则使用该值。

当未定义 COLUMNSLINES 时(这是常见情况),通过调用 os.get_terminal_size() 查询连接到 sys.__stdout__ 的终端。

如果无法成功查询终端大小,可能是因为系统不支持查询,或者因为我们没有连接到终端,则使用 fallback 参数中给出的值。 fallback 默认为 (80, 24),这是许多终端模拟器使用的默认大小。

返回的值是 os.terminal_size 类型的命名元组。

另请参阅:Single UNIX Specification,版本 2,其他环境变量

3.3 版本中新增。

在 3.11 版本中更改: 如果 os.get_terminal_size() 返回零值,也会使用 fallback 值。