Comment décompresser en toute sécurité, sans polluer le répertoire en cours en cas de tarbomb?

33

Projets Respectable libèrent des archives tar qui contiennent un seul répertoire, par exemple zyrgus-3.18.tar.gzcontient un zyrgus-3.18dossier qui contient à son tour src, build, dist, etc.

Mais certains projets punk mettent tout à la racine: '- (Cela entraîne un désordre total lors de la désarchivage. Créer un dossier manuellement à chaque fois est une douleur, et inutile la plupart du temps.

  • Existe-t-il un moyen très rapide de savoir si un fichier .tar ou .tar.gz contient plus d'un répertoire à la racine? Même pour une grande archive.
  • Ou mieux encore, existe-t-il un outil qui, dans de tels cas, créerait un répertoire (nom de l'archive sans l'extension) et mettrait tout à l'intérieur?
Nicolas Raoul
la source
2
Je pense qu'un emballage cassé mérite un rapport de bogue pour l'auteur du paquet.
14
Historiquement (depuis le milieu des années 90), je me suis toujours désintégré dans un sous-répertoire. Si tout est placé dans un seul répertoire (comme il se doit), son contenu peut ensuite être déplacé au bon endroit avec mv, vous pouvez alors supprimer le répertoire supplémentaire superflu. Deux étapes supplémentaires, certes, mais il vaut mieux nettoyer le gâchis d’un fichier tar mal construit.
TED
6
But some punk projects put everything at the root :'-(Et certains projets punk mettent tout dans un dossier de manière totalement inutile, sachant qu'ils le font déjà dans une archive englobante. Ainsi, lorsque vous téléchargez et décompressez le fichier dans son propre dossier, comme le ferait n'importe quel utilisateur intelligent, vous vous retrouverez avec tous les fichiers. contenu enfoui une autre couche. ;-)
Mason Wheeler
2
@MasonWheeler Il existe une sorte de "norme de facto" pour les archives tar qui contient tout dans un seul dossier.
Glglgl

Réponses:

30

patool gère différents types d'archives et crée un sous-répertoire au cas où l'archive contient plusieurs fichiers afin d'éviter d'encombrer le répertoire de travail avec les fichiers extraits.

Extraire l'archive

patool extract archive.tar

Pour obtenir une liste des formats pris en charge, utilisez patool formats.

Marco
la source
Pour votre information: trouvé à sourceforge.net/projects/patool . C'est un rpm et j'avais l'habitude aliende le convertir en deb pour Ubuntu.
Joe
patooldevrait être dans les dépôts pour Debian et Ubuntu si vous utilisez une version actuelle.
Marco
12

Vous pourriez faire quelque chose comme

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

pour voir quelles entrées de niveau supérieur un tar a; pipe à wc -lvérifier s'il y a plus d'un. Notez qu'il existe quelques cas d'échec, par exemple si le fichier tar contient les chemins de fichier du formulaire somedir/whateveret également ./somedir/whatever(ou quelque chose de plus fou); cela devrait être rare, cependant.

Cela lira l'intégralité du fichier tar avant de générer quoi que ce soit, à cause de la sort, mais il devrait être plus rapide que l'extraction car il ne s'agit que d'une lecture séquentielle et il peut ignorer les gros fichiers.

Si vous faites cela de manière interactive et le fichier peut être grand, vous pouvez changer sort -uà uniqet Control+ Csi elle imprime plus d'une chose.

Dougal
la source
2
sort | uniqpeut être raccourci à sort -u.
Marco
4
sauf si vous voulez faireuniq -c
cas
7

tu peux faire:

pax <some.tar

... pour lister le contenu d'un tarfichier.

si vous voulez savoir à combien de niveaux il va, vous pouvez faire:

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

vous pouvez explicitement interdire une explosion à l'extraction avec:

mkdir some.tar
pax -'rs|^|some.tar/|' <some.tar
Mikeserv
la source
2

Cela devrait faire ce que vous voulez. Je suis sûr que quelqu'un peut l'améliorer. Dans ces exemples, je suppose une archive compressée gzip car il s’agit de la plus courante.

Vous voulez une archive où il n'y a pas de nœuds frères dans l'arborescence de répertoires de niveau racine.

Chaque entrée de la liste de contenu tar doit commencer par le même modèle. Ce modèle est le chemin du répertoire de base que toutes les entrées de l’archive doivent partager. Si deux entrées ne commencent pas par le même motif, ce sont des frères et soeurs.

La première ligne de la liste de contenu tar vous indique le motif minimal à vérifier. C'est le BASEPATH.

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

Puis à tester pour tarballs explosifs dont vous avez besoin pour vérifier si une ligne de la liste de teneur en goudron ne commence par la BasePath.

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

Transformez ceci en une fonction shell:

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

À partir de là, vous pouvez écrire une fonction d'extraction d'archive tar sécurisée.

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 $?
}
Noah Spurrier
la source