当我在具有文件路径的
add()
对象上调用 tarfile
时,该文件将添加到与目录层次结构关联的 tarball 中。换句话说,如果我解压缩 tar 文件,则会复制原始目录层次结构中的目录。
有没有一种方法可以简单地添加一个没有目录信息的普通文件,以便解压生成的 tarball 生成一个平面文件列表?
使用 TarFile.add() 方法的 arcname 参数是匹配目的地的另一种便捷方法。
示例:您想要将目录 repo/a.git/ 存档到 tar.gz 文件,但您希望存档中的树根以 a.git/ 开头,而不是 repo/a .git/,您可以执行以下操作:
archive = tarfile.open("a.git.tar.gz", "w|gz")
archive.add("repo/a.git", arcname="a.git")
archive.close()
tarfile.addfile()
,在第一个参数TarInfo
对象中,您可以指定与您添加的文件不同的name
。
这段代码应该将
/path/to/filename
添加到 TAR 文件中,但会将其提取为 myfilename
:
tar.addfile(tarfile.TarInfo("myfilename.txt"), open("/path/to/filename.txt"))
也许您可以使用 TarFile.add(name, arcname) 的“arcname”参数。它采用文件在存档中的备用名称。
感谢@diabloneo,可以创建目录的选择性 tarball
def compress(output_file="archive.tar.gz", output_dir='', root_dir='.', items=[]):
"""compress dirs.
KWArgs
------
output_file : str, default ="archive.tar.gz"
output_dir : str, default = ''
absolute path to output
root_dir='.',
absolute path to input root dir
items : list
list of dirs/items relative to root dir
"""
os.chdir(root_dir)
with tarfile.open(os.path.join(output_dir, output_file), "w:gz") as tar:
for item in items:
tar.add(item, arcname=item)
>>>root_dir = "/abs/pth/to/dir/"
>>>compress(output_file="archive.tar.gz", output_dir=root_dir,
root_dir=root_dir, items=["logs", "output"])
以下是在不添加文件夹的情况下压缩
folder
中的文件列表的代码示例:
with tarfile.open(tar_path, 'w') as tar:
for filename in os.listdir(folder):
fpath = os.path.join(folder, filename)
tar.add(fpath, arcname=filename)
我一直在寻找类似的问题,但被重定向到此页面,因此我可能会为其他谷歌用户添加此问题。 就我而言,我想要一个 tar 文件,其中仅包含相对文件名,这将递归地工作。所以,一个可压缩的目录
/home/test/data
/home/test/data/content.txt
/home/test/data/files/file.txt
在 zip 中看起来像这样:
content.txt
files/file.txt
默认情况下,python
tarfile
将添加 /
作为额外条目。
我的目标是删除 tar 文件中的前导
/
条目,因为它被视为 ZipSlip 漏洞
当使用具有此类漏洞的 tar 时,您将收到警告
tar: Removing leading `/' from member names
我不确定为什么 python
tarfile
库没有简单的方法来处理这个问题,但我想出了这段代码,它完全符合我的要求:
def package_tar_recursive_without_root_folder(input_dir: str, output_file: str):
with tarfile.open(output_file, mode='w:gz') as archive:
for root, dirs, files in os.walk(input_dir):
for file in files:
file_path = os.path.join(root, file)
relative_path = os.path.relpath(file_path, input_dir)
archive.add(file_path, arcname=relative_path, recursive=False)
如果您想在 tar 文件中添加目录名称而不是其内容,您可以执行以下操作:
(1) 创建一个名为
empty
的空目录
(2) tf.add("empty", arcname=path_you_want_to_add)
这将创建一个名为
path_you_want_to_add
的空目录。