Tar
Tar.create
— 函数create(
[ predicate, ] dir, [ tarball ];
[ skeleton, ] [ portable = false ]
) -> tarball
predicate :: String --> Bool
dir :: AbstractString
tarball :: Union{AbstractString, AbstractCmd, IO}
skeleton :: Union{AbstractString, AbstractCmd, IO}
portable :: Bool
创建目录 dir
的 tar 归档文件(“tarball”)。生成的归档文件将写入路径 tarball
,或者如果未指定路径,则创建一个临时路径并由函数调用返回。如果 tarball
是一个 IO 对象,则 tarball 内容将写入该句柄(句柄保持打开状态)。
如果传递了 predicate
函数,则在递归搜索 dir
时遇到每个系统路径时都会调用它,并且只有当 predicate(path)
为真时,path
才包含在 tarball 中。如果 predicate(path)
对目录返回 false,则该目录将被完全排除:该目录下的任何内容都不会包含在归档文件中。
如果传递了 skeleton
关键字,则给定的文件或 IO 句柄将用作生成 tarball 的“骨架”。您可以通过将 skeleton
关键字传递给 extract
命令来创建骨架文件。如果使用该骨架文件调用 create
并且提取的文件没有更改,则会重新创建相同的 tarball。skeleton
和 predicate
参数不能一起使用。
如果 portable
标志为真,则会检查路径名称在 Windows 上的有效性,这确保它们不包含非法字符或具有保留的名称。有关详细信息,请参阅 https://stackoverflow.com/a/31976060/659248。
Tar.extract
— 函数extract(
[ predicate, ] tarball, [ dir ];
[ skeleton = <none>, ]
[ copy_symlinks = <auto>, ]
[ set_permissions = true, ]
) -> dir
predicate :: Header --> Bool
tarball :: Union{AbstractString, AbstractCmd, IO}
dir :: AbstractString
skeleton :: Union{AbstractString, AbstractCmd, IO}
copy_symlinks :: Bool
set_permissions :: Bool
将位于路径 tarball
的 tar 归档文件(“tarball”)提取到目录 dir
中。如果 tarball
是 IO 对象而不是路径,则归档内容将从该 IO 流中读取。归档文件将提取到 dir
,dir
必须是现有空目录或可以作为新目录创建的非现有路径。如果未指定 dir
,则归档文件将提取到一个临时目录中,该目录由 extract
返回。
如果传递了 predicate
函数,则在提取 tarball
时遇到每个 Header
对象时都会调用它,并且只有当 predicate(hdr)
为真时,才会提取该条目。这可以用于有选择地仅提取归档文件的部分内容,跳过导致 extract
抛出错误的条目,或在提取过程中记录提取的内容。
在传递给谓词函数之前,Header
对象会从 tarball 中的原始标头进行一些修改:path
字段已规范化,以删除 .
条目并将多个连续的斜杠替换为单个斜杠。如果条目的类型为 :hardlink
,则链接目标路径也将以相同的方式规范化,以便它与目标条目的路径匹配;size 字段设置为目标路径的大小(该路径必须是已查看的文件)。
如果传递了 skeleton
关键字,则提取的 tarball 的“骨架”将写入给定的文件或 IO 句柄。可以通过将 skeleton
关键字传递给 create
函数来使用此骨架文件重新创建相同的 tarball。skeleton
和 predicate
参数不能一起使用。
如果 copy_symlinks
为 true
,则不会像这样提取符号链接,而是如果它们在 tarball 内部并且可以这样做,则将它们提取为其链接到的内容的副本。非内部符号链接(例如,指向 /etc/passwd
的链接)不会被复制。以任何方式循环的符号链接也不会被复制,而是会被跳过。默认情况下,extract
将检测是否可以在 dir
中创建符号链接,如果无法创建,则会自动复制符号链接。
如果 set_permissions
为 false
,则不会在提取的文件上设置任何权限。
Tar.list
— 函数list(tarball; [ strict = true ]) -> Vector{Header}
list(callback, tarball; [ strict = true ])
callback :: Header, [ <data> ] --> Any
tarball :: Union{AbstractString, AbstractCmd, IO}
strict :: Bool
列出位于路径 tarball
的 tar 归档文件(“tarball”)的内容。如果 tarball
是 IO 句柄,则从该流中读取 tar 内容。返回一个 Header
结构体的向量。有关详细信息,请参阅 Header
。
如果提供了 callback
,则不会返回标头的向量,而是对每个 Header
调用 callback
。如果 tarball 中的项目数量很大或您希望在 tarball 中出现错误之前检查项目,这将非常有用。如果 callback
函数可以接受类型为 Vector{UInt8}
或 Vector{Pair{Symbol, String}}
的第二个参数,则它将使用原始标头数据的表示形式调用它,作为单个字节向量或作为将字段名称映射到该字段原始数据的对的向量(如果将这些字段连接在一起,则结果是标头的原始数据)。
默认情况下,如果 list
遇到 extract
函数拒绝提取的任何 tarball 内容,则会出错。使用 strict=false
,它将跳过这些检查并列出 tar 文件的所有内容,无论 extract
是否提取它们。请注意,恶意 tarball 可以执行各种巧妙且意想不到的操作来试图欺骗您执行某些不良操作。
如果 tarball
参数是骨架文件(请参阅 extract
和 create
),则 list
将从文件标头检测到这一点,并适当地列出或迭代骨架文件标头。
Tar.rewrite
— 函数rewrite(
[ predicate, ] old_tarball, [ new_tarball ];
[ portable = false, ]
) -> new_tarball
predicate :: Header --> Bool
old_tarball :: Union{AbstractString, AbtractCmd, IO}
new_tarball :: Union{AbstractString, AbtractCmd, IO}
portable :: Bool
将 old_tarball
重写为 create
生成的标准格式,同时还检查它是否不包含任何会导致 extract
引发错误的内容。这在功能上等同于执行
Tar.create(Tar.extract(predicate, old_tarball), new_tarball)
但是,它永远不会将任何内容提取到磁盘,而是使用 seek
函数来导航旧 tarball 的数据。如果没有传递 new_tarball
参数,则新的 tarball 将写入一个临时文件,其路径将被返回。
如果传递了 predicate
函数,则在提取 old_tarball
时遇到每个 Header
对象时都会调用它,并且除非 predicate(hdr)
为真,否则该条目将被跳过。这可以用于有选择地仅重写归档文件的部分内容,跳过会导致 extract
抛出错误的条目,或在重写过程中记录遇到的内容。
在传递给谓词函数之前,Header
对象会从 tarball 中的原始标头进行一些修改:path
字段已规范化,以删除 .
条目并将多个连续的斜杠替换为单个斜杠。如果条目的类型为 :hardlink
,则链接目标路径也将以相同的方式规范化,以便它与目标条目的路径匹配;size 字段设置为目标路径的大小(该路径必须是已查看的文件)。
如果 portable
标志为真,则会检查路径名称在 Windows 上的有效性,这确保它们不包含非法字符或具有保留的名称。有关详细信息,请参阅 https://stackoverflow.com/a/31976060/659248。
Tar.tree_hash
— 函数tree_hash([ predicate, ] tarball;
[ algorithm = "git-sha1", ]
[ skip_empty = false ]) -> hash::String
predicate :: Header --> Bool
tarball :: Union{AbstractString, AbstractCmd, IO}
algorithm :: AbstractString
skip_empty :: Bool
计算tar包包含的文件树的树哈希值。默认情况下,它使用git的树哈希算法和SHA1安全哈希函数(就像当前版本的git一样)。这意味着对于任何git可以表示其文件树的tar包——即仅包含文件、符号链接和非空目录的tar包——此函数计算的哈希值将与git为该文件树计算的哈希值相同。请注意,tar包可以表示包含空目录的文件树,而git无法存储这些文件树,并且此函数可以为这些文件树生成哈希值,默认情况下(请参阅下面的skip_empty
以了解如何更改此行为),这些哈希值将与省略这些空目录的tar包的哈希值不同。简而言之,哈希函数与git在所有git可以表示的树上达成一致,但以一致的方式将可哈希树的域扩展到git无法表示的其他树。
如果传递了predicate
函数,则在处理tarball
时遇到每个Header
对象时都会调用它,并且只有当predicate(hdr)
为真时才会对条目进行哈希处理。这可以用来选择性地仅哈希归档的一部分,跳过导致extract
抛出错误的条目,或者记录在哈希过程中提取的内容。
在传递给谓词函数之前,Header
对象会从 tarball 中的原始标头进行一些修改:path
字段已规范化,以删除 .
条目并将多个连续的斜杠替换为单个斜杠。如果条目的类型为 :hardlink
,则链接目标路径也将以相同的方式规范化,以便它与目标条目的路径匹配;size 字段设置为目标路径的大小(该路径必须是已查看的文件)。
当前支持的algorithm
值包括git-sha1
(默认值)和git-sha256
,后者使用与git-sha1
相同的基本算法,但用SHA2-256替换了SHA1哈希函数,SHA2-256是git未来将过渡使用的哈希函数(由于已知的SHA1攻击)。未来可能会添加对其他文件树哈希算法的支持。
skip_empty
选项控制是否将tar包中递归不包含文件或符号链接的目录包含在哈希中或忽略。通常,如果您正在对tar包或文件树的内容进行哈希处理,您会关心所有目录,而不仅仅是非空目录,因此将这些目录包含在计算的哈希中是默认行为。那么为什么此函数甚至提供跳过空目录的选项呢?因为git拒绝存储空目录,并且如果您尝试将它们添加到存储库中,它将忽略它们。因此,如果您通过将文件添加到git存储库并然后请求git获取树哈希来计算参考树哈希,那么您获得的哈希值将与tree_hash
使用skip_empty=true
计算的哈希值匹配。换句话说,此选项允许tree_hash
模拟git如何对包含空目录的树进行哈希处理。但是,如果您正在对可能包含空目录的树进行哈希处理(即不来自git存储库),建议您使用不忽略空目录的工具(例如此工具)对其进行哈希处理。
Tar.Header
— 类型Header
类型是一个结构体,表示tar文件中单个记录的基本元数据,其定义如下
struct Header
path :: String # path relative to the root
type :: Symbol # type indicator (see below)
mode :: UInt16 # mode/permissions (best viewed in octal)
size :: Int64 # size of record data in bytes
link :: String # target path of a symlink
end
类型用以下符号表示:file
、hardlink
、symlink
、chardev
、blockdev
、directory
、fifo
,或者对于未知类型,类型标志字符作为符号。请注意,extract
拒绝提取除file
、symlink
和directory
之外的其他类型的记录;list
仅在使用strict=false
调用时才会列出其他类型的记录。
tar格式包含有关记录的各种其他元数据,包括用户和组ID、用户和组名称以及时间戳。Tar
包在设计上完全忽略了这些元数据。创建tar文件时,这些字段始终设置为零/空。读取tar文件时,除了验证每个标头记录的所有字段的标头校验和外,这些字段将被忽略。