J'ai un tas de fichiers tar
dans un répertoire et je veux en extraire tous les fichiers à la fois. Mais cela ne semble rien faire:
$ tar xf *.tar
Que se passe t-il ici? Comment décompresser un tas de fichiers à la fois?
À l'origine, la commande tar
était destinée à être utilisée avec des périphériques de bande magnétique. Puisqu'il était logique d'exécuter tar
sur un périphérique à la fois, la syntaxe a été conçue pour supposer un et un seul périphérique. Le premier fichier ou répertoire transmis était supposé être le périphérique qui contenait l'archive en question et tout autre fichier ou répertoire où le contenu de l'archive devait être inclus dans l'opération. Ainsi, pour l'extraction tar
(l'option x
), le premier fichier transmis serait l'archive et tous les autres fichiers seraient les fichiers à extraire. Donc, s'il y a deux *.tar
fichiers (par exemple a.tar
et b.tar
) votre commande s'étendrait à:
$ tar xf a.tar b.tar
Sauf si a.tar
contient un fichier nommé b.tar
, la commande tar
n'a rien à faire et se ferme silencieusement. De façon ennuyeuse, la version Solaris de tar
ne signale aucun problème ni dans le code de retour ni avec l'option détaillée (v
). Pendant ce temps, GNU tar
résultats 2
et les spams STDERR
même avec l'option verbose désactivée:
tar: b.tar: Not found in archive
tar: Exiting with failure status due to previous errors
Il est trop tard de réécrire tar
pour accepter plusieurs fichiers d'archive en entrée, mais il n'est pas trop difficile de contourner la limitation.
Pour la plupart des gens, exécuter tar
plusieurs fois pour plusieurs archives est l'option la plus appropriée. Passer un seul nom de fichier à tar xf
extraira tous les fichiers archivés comme on pourrait s'y attendre. Une approche consiste à utiliser une boucle Shell for
:
$ for f in *.tar; do tar xf "$f"; done
Une autre méthode consiste à utiliser xargs
:
$ ls *.tar | xargs -i tar xf {}
Alternativement, vous pouvez utiliser l'un d'un certain nombre de lecteurs de fichiers alternatifs tar
. Enfin, le programmeur vraiment dédié pourrait facilement écrire un remplacement tar
qui fonctionne exactement comme vous le souhaitez. Le format est simple et de nombreux langages de programmation ont des bibliothèques disponibles pour lire les fichiers tar
. Si vous êtes un programmeur Perl, par exemple, jetez un œil au Archive::Tar
module.
Détacher aveuglément un tas de fichiers peut provoquer des problèmes inattendus. Le plus évident est qu'un nom de fichier particulier peut être inclus dans plusieurs fichiers tar
. Puisque tar
écrase les fichiers par défaut, la version exacte du fichier avec lequel vous vous retrouvez dépendra de l'ordre dans lequel les archives sont traitées. Plus troublant, vous pouvez vous retrouver avec une copie corrompue du fichier si vous essayez cette optimisation "intelligente":
for f in *.tar; do
tar xf "$f" &
done
wait
Si les deux a.tar
et b.tar
contient le même fichier et essaie de l'extraire en même temps, les résultats sont imprévisibles.
Un problème connexe, en particulier lors de la collecte d'archives à partir d'une source non fiable, est la possibilité d'un tarbomb .
Une solution partielle serait de créer automatiquement un nouveau répertoire dans lequel extraire:
for f in *.tar; do
d=`basename "$f" .tar`
mkdir "$d"
(cd "$d" && tar xf "../$f")
done
Cela n'aidera pas si un fichier est spécifié dans l'archive avec un chemin absolu (qui est normalement un signe d'intention malveillante). L'ajout de ce type de vérification est laissé comme exercice au lecteur.
Si tous les fichiers tar sont dans le même dossier, je le fais dans tcsh Shell. Fonctionne tout le temps.
find -iname \*.tar -exec tar -xvf {} \;
C'est la même chose que la réponse ci-dessus, un peu plus concise je pense.
find . -maxdepth 1 -name '*.tar' -exec tar -xf '{}' \;