如何安全解压缩,如果发生炸弹,又不会污染当前目录?


33

尊敬的项目发布包含单个目录tar归档,例如zyrgus-3.18.tar.gz包含一个zyrgus-3.18文件夹中又包含srcbuilddist,等。

但是一些朋克项目将所有内容都放在了根目录:'-(取消存档时会造成混乱。每次手动创建文件夹都是一件很痛苦的事情,并且在大多数情况下是不必要的。

  • 是否有超快速的方法来判断.tar或.tar.gz文件在其根目录中是否包含多个目录?即使是很大的档案。
  • 甚至更好的是,是否有一种工具可以在这种情况下创建目录(不带扩展名的档案名称)并将所有内容放入其中?


2
我认为损坏的包装值得向包装作者提交错误报告。

14
从90年代中期开始,我就一直不解压缩到子目录中。如果将它们全部放在一个目录中(应该是),则可以使用mv将其内容移到正确的位置,然后可以删除多余的多余目录。是的,还有两个额外的步骤,但是它可以清除错误的tar文件中的混乱情况。
TED

6
But some punk projects put everything at the root :'-(一些朋克项目完全不必要地将所有内容都放在一个文件夹中,因为它们已经将所有内容都放在了一个封闭的存档中,因此当您像任何智能用户一样将其下载并解压缩到其自己的文件夹中时,最终内容又埋了一层。;-)
Mason Wheeler

2
@MasonWheeler tar存档有一种“事实上的标准”,可以将所有内容都放在一个文件夹中。
glglgl 2015年

Answers:


30

如果归档文件包含多个文件,则patool会处理各种类型的归档文件并创建一个子目录,以防止提取的文件使工作目录混乱。

提取档案

patool extract archive.tar

要获取支持的格式列表,请使用patool formats


仅供参考:在sourceforge.net/projects/patool中找到了它。这是一个rpm,我曾经alien将其转换为Ubuntu的deb。

patool如果您正在运行当前版本,则应该在Debian和Ubuntu的回购协议中。
Marco Marco

12

你可以做类似的事情

tar tf thefile.tar | cut -d/ -f1 | sort -u

查看tar有哪些顶级条目;wc -l检查是否有多个管道。请注意,在某些情况下,此操作将失败,例如,如果tar包含以下格式的文件路径(somedir/whatever./somedir/whatever可能更疯狂);但是,这应该不常见。

由于的缘故sort,它将在输出任何内容之前先读取整个tar文件,尽管它应该比实际提取要快,因为它只是一次顺序读取,并且可以跳过大文件。

如果您以交互方式进行此操作,并且文件可能很大,那么如果打印出的内容不止一件,则可以更改sort -uuniqand Control+ C


2
sort | uniq可以缩短为sort -u
马可(Marco)

4
除非你想做的事uniq -c
中科院

7

你可以做:

pax <some.tar

...列出tar文件的内容。

如果您想知道它深入了多少层,可以执行以下操作:

pax <some.tar | tr -dc /\\n | sort -r | head -n1

您可以使用以下命令明确禁止爆炸:

mkdir some.tar
pax -'rs|^|some.tar/|' <some.tar

2

这应该做您想要的。我相信有人可以改善它。在这些示例中,我假定使用gzip压缩的tar存档,因为这是最常见的。

您需要一个在根目录目录树中没有兄弟节点的归档文件。

tar内容列表中的每个条目都必须以相同的模式开头。此模式是归档中所有条目必须共享的基本目录路径。如果任何两个条目不是以相同的模式开头,则它们是同级。

tar内容列表中的第一行将为您提供所需检查的最小模式。这是BASEPATH。

BASEPATH=$(tar ztf example.tar.gz | (read line; echo $line))

然后,以测试你需要检查,如果爆炸压缩包的任何焦油含量列表的行与基本路径开始。

tar ztf example.tar.gz | grep -qv "^${BASEPATH}"

把它变成一个shell函数:

is_explosive() {
    TARBALL_NAME=$1
    tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
    return $?
}

从这里您可以编写一个安全的tar存档提取功能。

is_explosive() {
    TARBALL_NAME=$1
    tar ztf "${TARBALL_NAME}" | grep -qv "^$(tar ztf "${TARBALL_NAME}" | (read line; echo ${line}))"
    return $?
}

safe_tar_x() {
    TARBALL_NAME=$1
    if is_explosive ${TARBALL_NAME}; then
        SUBDIR=${TARBALL_NAME%.tar.gz}
        SUBDIR=${SUBDIR##*/}
        mkdir "${SUBDIR}"
        echo "WARNING: This tarball is explosive. Opening in subdirectory, ${SUBDIR}, for safety." >&2
    else
        SUBDIR="."
    fi
    # Tar quirks: "--directory" must be last, and using more than
    #     one option group requires that all groups start with a dash.
    tar -zxf "${TARBALL_NAME}" --directory "${SUBDIR}"
    return $?
}

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.