Transformez les chemins d'une archive tar sans l'extraire


10

GNU tar(1)a une option intéressante appelée --transform. Depuis la page de manuel:

--transform, --xform EXPRESSION
utilise sed remplace EXPRESSION pour transformer les noms de fichiers

Cela permet de transformer les noms de chemin à la volée lors de l'extraction de l'archive afin que vous puissiez contrôler où et comment elle sera extraite.

Ma question est, existe-t-il un moyen d'effectuer une transformation similaire in situ ; c'est-à-dire, sans extraire l'archive?

Exemple

[user@host]$ tar tf test.tar
./foo/blah  ./foo/bleh
[user@host]$ some_deep_magic 's/foo/bar/' test.tar
[user@host]$ tar tf test.tar
./bar/blah  ./bar/bleh

Cas d'utilisation

Je distribue une tararchive à des utilisateurs finaux fondamentalement ignorants et je voudrais qu'elle soit extraite dans le bon chemin sans interférence de ma part. J'essaie d'éviter la solution triviale d'extraire l'archive, de renommer les répertoires et de remballer car l'archive est trop grande.


Pourquoi ne transformez-vous pas les noms lors de sa création?
Jose Luis Martin

@JoseLuisMartin À droite. Mon cas d'utilisation est que l'archive est déjà là et, comme je l'ai dit, j'aimerais éviter le déballage, la transformation et le reconditionnement.
Joseph R.

1
Vous pouvez modifier le flux tar sans l'extraire réellement sur le disque: github.com/mafintosh/tar-stream#modifying-existing-tarballs , perldoc.perl.org/5.10.1/Archive/Tar.html , etc
vladr

Réponses:


3

Vous pouvez monter l'archive avec archivemount ou mountavfs et la recréer à nouveau

archivemount tarfile.tar /mnt
cd /mnt
tar cf /tmp/tarfile.tar --transform 's/foo/bar/' .

les opérations d'écriture sur le système de fichiers d'archives effectueront une réécriture complète sur umount, donc ne semblent pas une bonne option pour les gros fichiers.

ÉDITER

Je ne connais pas les détails de l'implémentation, mais il semble que nous enregistrions les fichiers d'écriture à l'étape du système de fichiers.

Il suffit de tester pour résoudre les types, (sur un goudron de mon / usr)

#!/bin/bash

# try to avoid slab cache issues 
cat /tmp/usr.tar > /dev/null

T="$(date +%s)"
tar xf /tmp/usr.tar
tar cf usr.tar usr --transform 's/usr/foo/'
T="$(($(date +%s)-T))"
echo "Tar/Untar seconds: ${T}"

T="$(date +%s)"
archivemount -o readonly -o nobackup /tmp/usr.tar /mnt
tar cf usr.tar /mnt  --transform 's/usr/foo/'
umount /mnt
T="$(($(date +%s)-T))"
echo "Archivemount seconds: ${T}"

T="$(date +%s)"
mountavfs
cd '/root/.avfs/tmp/usr.tar#'
tar cf /tmp/test/usr.tar   --transform 's/usr/foo/' .
T="$(($(date +%s)-T))"
echo "Avfs seconds: ${T}"

Production:

Tar/Untar seconds: 480
Archivemount seconds:  failure, a lot of read errors.
Avfs seconds: 217

Alors Avfs gagne! .


1
+1 Nouvelle commande intéressante. Mais en quoi cette approche est-elle différente du déballage de l'archive? Je ne parle pas de mise en œuvre, mais de performance.
Joseph R.
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.