shutil — 高階檔案操作

原始碼: Lib/shutil.py


shutil 模組提供了許多針對檔案和檔案集合的高階操作。特別是,它提供了支援檔案複製和刪除的函式。有關單個檔案的操作,請參閱 os 模組。

警告

即使是更高階的檔案複製函式(shutil.copy()shutil.copy2())也無法複製所有檔案元資料。

在 POSIX 平臺上,這意味著檔案所有者、組以及 ACL 會丟失。在 Mac OS 上,資源分叉和其他元資料不會被使用。這意味著資源會丟失,檔案型別和建立者程式碼將不正確。在 Windows 上,檔案所有者、ACL 和備用資料流不會被複制。

目錄和檔案操作

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

檔案類物件 fsrc 的內容複製到檔案類物件 fdst。整數 length(如果給定)是緩衝區大小。特別是,負數 length 值表示不分塊迴圈源資料來複制資料;預設情況下,資料是分塊讀取的,以避免不受控制的記憶體消耗。請注意,如果 fsrc 物件的當前檔案位置不是 0,則只複製從當前檔案位置到檔案末尾的內容。

copyfileobj() 保證在複製完成後目標流已被重新整理。如果您想在複製操作完成後從目標讀取(例如,讀取從 HTTP 流複製的臨時檔案的內容),則必須確保在嘗試讀取目標檔案之前已在檔案類物件上呼叫了 flush()close()

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.SpecialFileError

copyfile()copytree() 嘗試複製命名管道時,會引發此異常。

2.7 版本新增。

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_symlinksTruecopystat() 可以修改符號連結的許可權位。

  • 如果 os.utime in os.supports_follow_symlinksTruecopystat() 可以修改符號連結的最後訪問時間和修改時間。

  • 如果 os.chflags in os.supports_follow_symlinksTruecopystat() 可以修改符號連結的標誌。(os.chflags 並非在所有平臺上都可用。)

在某些或所有此功能不可用的平臺上,當被要求修改符號連結時,copystat() 將複製所有它能複製的內容。copystat() 絕不會返回失敗。

請參閱 os.supports_follow_symlinks 獲取更多資訊。

引發帶有引數 srcdst審計事件 shutil.copystat

3.3 版本中已更改: 添加了 follow_symlinks 引數並支援 Linux 擴充套件屬性。

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

將檔案 src 複製到檔案或目錄 dstsrcdst 應為 路徑類物件 或字串。如果 dst 指定一個目錄,檔案將使用 src 的基本檔名複製到 dst 中。如果 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

引發帶有引數 srcdst審計事件 shutil.copystat

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 樹中的相應檔案覆蓋。

引發帶有引數 srcdst審計事件 shutil.copytree

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() 返回的元組。

參見

rmtree 示例 用於處理包含只讀檔案的目錄樹刪除的示例。

引發帶有引數 pathdir_fd審計事件 shutil.rmtree

3.3 版本中已更改: 添加了一個防符號連結攻擊版本,如果平臺支援基於 fd 的函式,則會自動使用。

3.8 版本中已更改: 在 Windows 上,在刪除目錄連線之前,不再刪除目錄連線的內容。

3.11 版本中已更改: 添加了 dir_fd 引數。

3.12 版本中已更改: 添加了 onexc 引數,棄用了 onerror

3.13 版本中已更改: rmtree() 現在忽略除頂級路徑之外的所有 FileNotFoundError 異常。除 OSError 及其子類之外的異常現在總是傳播給呼叫方。

指示當前平臺和實現是否提供防符號連結攻擊版本的 rmtree()。目前,這僅適用於支援基於 fd 的目錄訪問函式的平臺。

在 3.3 版本加入。

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

遞迴地將檔案或目錄 (src) 移動到另一個位置並返回目標。

如果 dst 是一個現有目錄或指向目錄的符號連結,則 src 將移動到該目錄中。該目錄中的目標路徑不得已存在。

如果 dst 已經存在但不是目錄,它可能會被覆蓋,具體取決於 os.rename() 的語義。

如果目標在當前檔案系統上,則使用 os.rename()。否則,src 將使用 copy_function 複製到目標,然後刪除。對於符號連結,將建立一個指向 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 將執行的可執行檔案的路徑。如果沒有可執行檔案將被呼叫,則返回 None

mode 是傳遞給 os.access() 的許可權掩碼,預設情況下確定檔案是否存在且可執行。

path 是一個“PATH 字串”,指定要查詢的目錄,由 os.pathsep 分隔。當未指定 path 時,PATH 環境變數從 os.environ 讀取,如果未設定則回退到 os.defpath

如果 cmd 包含目錄元件,which() 只直接檢查指定的路徑,而不搜尋 path 或系統 PATH 環境變數中列出的目錄。

在 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.copy_file_range()os.sendfile()

在 Solaris 上,使用 os.sendfile()

在 Windows 上,shutil.copyfile() 使用更大的預設緩衝區大小(1 MiB 而不是 64 KiB),並使用基於 memoryview()shutil.copyfileobj() 變體。

如果快速複製操作失敗且沒有資料寫入目標檔案,則 shutil 將靜默回退到內部使用效率較低的 copyfileobj() 函式。

3.8 版本中已更改。

3.14 版本中已更改: Solaris 現在使用 os.sendfile()

3.14 版本中已更改: 在支援的 Linux 檔案系統上,可以透過 os.copy_file_range() 內部使用寫時複製或伺服器端複製。

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 模組可用)或“zstdtar”(如果 compression.zstd 模組可用)。

root_dir 是將作為歸檔根目錄的目錄,歸檔中的所有路徑都將相對於它;例如,我們通常在建立歸檔之前 chdir 到 root_dir

base_dir 是我們開始歸檔的目錄;即 base_dir 將是歸檔中所有檔案和目錄的共同字首。base_dir 必須相對於 root_dir 給出。有關如何將 base_dirroot_dir 一起使用,請參閱 帶有 base_dir 的歸檔示例

root_dirbase_dir 都預設為當前目錄。

如果 dry_run 為 true,則不建立歸檔,但會將要執行的操作記錄到 logger 中。

ownergroup 用於建立 tar 歸檔。預設情況下,使用當前所有者和組。

logger 必須是與 PEP 282 相容的物件,通常是 logging.Logger 的例項。

verbose 引數未使用且已棄用。

引發帶有引數 base_nameformatroot_dirbase_dir審計事件 shutil.make_archive

備註

當使用 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 模組可用)。

  • zstdtar: Zstandard 壓縮的 tar 檔案(如果 compression.zstd 模組可用)。

您可以使用 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 具有自定義屬性 function.supports_root_dir 且設定為 True,則 root_dir 引數將作為關鍵字引數傳遞。否則,在呼叫 function 之前,程序的當前工作目錄將暫時更改為 root_dir。在這種情況下,make_archive() 不是執行緒安全的。

如果給定 extra_args,它是一個 (name, value) 對的序列,當使用歸檔器可呼叫物件時,它們將用作額外的關鍵字引數。

description 用於 get_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”或“zstdtar”。或任何其他使用 register_unpack_format() 註冊的格式。如果未提供,unpack_archive() 將使用歸檔檔名副檔名,並檢視是否有為此副檔名註冊的解壓器。如果未找到,則會引發 ValueError

僅關鍵字引數 filter 會傳遞給底層解壓函式。對於 zip 檔案,不接受 filter。對於 tar 檔案,建議使用 'data'(Python 3.14 以來預設),除非使用 tar 和類 UNIX 檔案系統特有的功能。(有關詳細資訊,請參閱 解壓過濾器。)

引發帶有引數 filenameextract_dirformat審計事件 shutil.unpack_archive

警告

切勿在未經事先檢查的情況下從不受信任的來源提取歸檔。檔案可能會在 extract_dir 引數中指定的路徑之外建立,例如具有以“/”開頭的絕對檔名或具有兩個點“..”的檔名的成員。

自 Python 3.14 以來,所有內建格式(zip 和 tar 檔案)的預設設定都將阻止此類最危險的安全問題,但不會阻止 所有 意外行為。閱讀 進一步驗證的提示 部分以瞭解 tar 特定的詳細資訊。

3.7 版本中已更改: filenameextract_dir 都接受 路徑類物件

3.12 版本中已更改: 添加了 filter 引數。

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

註冊解壓格式。name 是格式的名稱,extensions 是與格式對應的副檔名列表,例如 Zip 檔案的 .zip

function 是用於解包歸檔的可呼叫物件。可呼叫物件將接收

  • 歸檔的路徑,作為位置引數;

  • 歸檔必須解壓到的目錄,作為位置引數;

  • 可能有一個 filter 關鍵字引數,如果它已傳遞給 unpack_archive()

  • 附加的關鍵字引數,由 extra_args 指定為 (name, value) 元組的序列。

可以提供 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 模組可用)。

  • zstdtar: Zstandard 壓縮的 tar 檔案(如果 compression.zstd 模組可用)。

您可以使用 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/myarchive.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, Version 2, 其他環境變數

在 3.3 版本加入。

版本 3.11 中的變化: 如果 os.get_terminal_size() 返回零,也會使用 fallback 值。