tar: ajoutez tous les fichiers et répertoires dans le répertoire courant INCLUANT .svn et ainsi de suite


89

J'essaye de tar.gz un répertoire et utilise

tar -czf workspace.tar.gz *

Le tar résultant inclut les .svnrépertoires dans les sous-répertoires mais PAS dans le répertoire courant (car il *est étendu uniquement aux fichiers `` visibles '' avant d'être transmis à tar

j'ai essayé de

tar -czf workspace.tar.gz .à la place, mais j'obtiens une erreur parce que '.' a changé lors de la lecture:

tar: ./workspace.tar.gz: file changed as we read it

Existe-t-il une astuce pour faire *correspondre tous les fichiers (y compris le préfixe point) dans un répertoire?

(en utilisant bash sur Linux SLES-11 (2.6.27.19)


5
Peut-être que cette question appartient au superutilisateur?
Peter Jaric

Réponses:


75

Ne créez pas le fichier tar dans le répertoire que vous empaquetez:

tar -czf /tmp/workspace.tar.gz .

fait l'affaire, sauf qu'il extraira les fichiers dans tout le répertoire actuel lorsque vous décompressez. Mieux vaut faire:

cd ..
tar -czf workspace.tar.gz workspace

ou, si vous ne connaissez pas le nom du répertoire dans lequel vous étiez:

base=$(basename $PWD)
cd ..
tar -czf $base.tar.gz $base

(Cela suppose que vous n'avez pas suivi les liens symboliques pour vous rendre là où vous êtes et que le shell n'essaie pas de vous deviner en sautant en arrière à travers un lien symbolique - bashn'est pas digne de confiance à cet égard. Si vous devez vous inquiéter à ce sujet, utiliser cd -P ..pour faire un répertoire de changement physique. Stupide que ce ne soit pas le comportement par défaut à mon avis - déroutant, au moins, pour ceux pour qui cd ..n'ont jamais eu de signification alternative.)


Un commentaire dans la discussion dit:

Je [...] dois exclure le répertoire supérieur et [...] je dois placer le tar dans le répertoire de base.

La première partie du commentaire n'a pas beaucoup de sens - si le fichier tar contient le répertoire actuel, il ne sera pas créé lorsque vous extrayez le fichier de cette archive car, par définition, le répertoire actuel existe déjà (sauf dans des circonstances très étranges ).

La deuxième partie du commentaire peut être traitée de deux manières:

  1. Soit: créez le fichier ailleurs - /tmpest un emplacement possible - puis replacez-le à l'emplacement d'origine une fois qu'il est terminé.
  2. Ou: si vous utilisez GNU Tar, utilisez l' --exclude=workspace.tar.gzoption. La chaîne après le =est un modèle - l'exemple est le modèle le plus simple - une correspondance exacte. Vous devrez peut-être spécifier --exclude=./workspace.tar.gzsi vous travaillez dans le répertoire courant contrairement aux recommandations; vous devrez peut-être spécifier --exclude=workspace/workspace.tar.gzsi vous augmentez d'un niveau comme suggéré. Si vous avez plusieurs fichiers tar à exclure, utilisez ' *', comme dans --exclude=./*.gz.

1
Bonne réponse mais j'ai une situation où je suis obligé d'exécuter cette commande dans le répertoire qui doit être compressé. Je n'ai pas les autorisations nécessaires pour l'exécuter à l'extérieur.
Hexodus

Un endroit parfait pour emballer est / tmp à coup sûr.
Andre Fellows

46

Si vous ne voulez vraiment pas inclure le répertoire top dans l'archive tar (et c'est généralement une mauvaise idée):

tar czf workspace.tar.gz -C /path/to/workspace .

J'ai besoin d'exclure le répertoire supérieur et j'ai besoin de placer le tar dans le répertoire de base.
Micha

@Micha crée un script bash pour archiver et copier le fichier après
Fedir RYKHTIK

2
Il vous manque le - dans -czf je pense.
UpTheCreek

10
man tar: Le premier argument de tar doit être une fonction; soit l'une des lettres Acdrtux, soit l'un des longs noms de fonction. Une lettre de fonction n'a pas besoin d'être précédée de- , et peut être combinée avec d'autres options à une seule lettre.
rkhayrov

4
Ne fonctionne toujours pas, j'ai toujours le "." comme premier répertoire dans mon tarball
A. Gille

43

Il y a quelques étapes à suivre:

  1. Remplacez *par .pour inclure également les fichiers cachés.
  2. Pour créer l'archive dans le même répertoire, a --exclude=workspace.tar.gzpeut être utilisé pour exclure l'archive elle-même.
  3. Pour éviter l' tar: .: file changed as we read iterreur lorsque l'archive n'est pas encore créée, assurez-vous qu'elle existe (par exemple en utilisant touch), afin que --exclude corresponde au nom du fichier d'archive. (Il ne correspond pas au fichier n'existe pas)

Combiné, cela donne le script suivant:

touch workspace.tar.gz
tar -czf workspace.tar.gz --exclude=workspace.tar.gz .

7
J'ai lu toutes les réponses et tous les commentaires et c'est la meilleure façon de créer une archive tar dans le même répertoire. De cette réponse, j'ai également compris pourquoi cette erreur se produit.
Szymon Sadło

Si vous voulez voir les progrès alors qu'il est la compression de votre fichier tar, vous pouvez ajouter un drapeau supplémentaire pour --verbose, comme suit: -czvf.
Mastrianni

18

dans le répertoire que vous voulez compresser (répertoire actuel) essayez ceci:

tar -czf workspace.tar.gz . --exclude=./*.gz

2
Mais maintenant, il se plaint que le fichier "." changé lors de la lecture. Puis-je être sûr que tous les fichiers ont été inclus?
Jaan

1
Cela exclut tous les .gzfichiers du répertoire.
omerfarukdogan

12

Vous pouvez inclure les répertoires cachés en retournant dans un répertoire et en faisant:

cd ..
tar czf workspace.tar.gz workspace

En supposant que le répertoire que vous vouliez gzip s'appelait workspace.


Et cela évite également le problème de changement de fichier.
Jonathan Leffler

Ne fonctionne pas lorsque l'utilisateur n'a aucune autorisation d'écriture dans le dossier parent.
Joachim Wagner

Exactement @JoachimWagner!
p01ymath

1
@JoachimWagner. Si vous ne disposez pas de l'autorisation d'écriture, modifiez-la en:tar -czf /path/to/where/you/do/have/permission/workspace.tar.gz workspace
bramp

1
J'ai dû sortir -avant le czfpour que ça marche. Sinon, je recevais Cannot stat: No such file or directoryun message d'erreur.
Phemelo Khetho

6

Vous pouvez corriger le .formulaire en utilisant --exclude:

tar -czf workspace.tar.gz --exclude=workspace.tar.gz .

5

Mise à jour: j'ai ajouté un correctif pour le commentaire de l'OP.

tar -czf workspace.tar.gz .

va en effet changer le répertoire courant, mais pourquoi ne pas placer le fichier ailleurs?

tar -czf somewhereelse/workspace.tar.gz .
mv somewhereelse/workspace.tar.gz . # Update

Le fichier sera traité par la suite et doit être dans l'espace de travail - c'est un peu moche mais c'est juste nécessaire (le tout est juste une solution de contournement ...)
Micha

OK, je vais ajouter un correctif pour ça :)
Peter Jaric

Et si vous avez besoin de pouvoir l'exécuter à plusieurs reprises, ajoutez «rm workspace.tar.gz» avant la ligne tar.
Peter Jaric

Si vous voulez tarer un lecteur entier, dans ce même lecteur, il semble que vous n'ayez pas beaucoup d'options.
BeeOnRope

4

En fait, le problème vient des options de compression. L'astuce est de diriger le résultat du tar vers un compresseur au lieu d'utiliser les options intégrées. Incidemment, cela peut également vous donner une meilleure compression, car vous pouvez définir des options de compression supplémentaires.

Goudron minimal:

tar --exclude=*.tar* -cf workspace.tar .

Conduisez vers un compresseur de votre choix. Cet exemple est détaillé et utilise xz avec une compression maximale:

tar --exclude=*.tar* -cv . | xz -9v >workspace.tar.xz

La solution a été testée sur Ubuntu 14.04 et Cygwin sur Windows 7. C'est une réponse wiki de la communauté, alors n'hésitez pas à modifier si vous repérez une erreur.


Merci! Sauvé ma vie
Steven

2

Le problème avec la plupart des solutions proposées ici est que tar contient ./au début de chaque entrée. Donc, cela se traduit par un .répertoire lors de son ouverture via le compresseur GUI. Donc ce que j'ai fini par faire, c'est:

ls -1A | xargs -d "\n" tar cfz my.tar.gz

Si vous en avez déjà my.tar.gzdans le répertoire courant, vous voudrez peut-être grep ceci:

ls -1A | grep -v my.tar.gz | xargs -d "\n" tar cfz my.tar.gz

Sachez que xargs a une certaine limite (voir xargs --show-limits). Donc, cette solution ne fonctionnerait pas si vous essayez de créer un package contenant de nombreuses entrées (répertoires et fichiers) sur un répertoire que vous essayez de tarer.


1

Une bonne question. Dans ZSH, vous pouvez utiliser le modificateur globbing (D), qui signifie "dotfiles". Comparer:

ls $HOME/*

et

ls $HOME/*(D)

Cela exclut correctement les entrées de répertoire spéciales .et ... Dans Bash, vous pouvez utiliser .*pour inclure explicitement les fichiers dotfiles:

ls $HOME/* $HOME/.*

Mais cela inclut .et ..aussi, donc ce n'est pas ce que vous recherchiez. Je suis sûr qu'il existe également un moyen de faire *correspondre les fichiers dotfiles dans bash.


Dans bash, utilisez .??*pour faire correspondre tous les fichiers de points non .et ... Cela n'obtient pas de fichiers de points à un seul caractère (comme .a). Pour les obtenir aussi, utilisez le plus compliqué .[^.]*.
Scott Minster

1

Encore une autre solution, en supposant que le nombre d'éléments dans le dossier n'est pas énorme:

tar -czf workspace.tar.gz `ls -A`

( ls -Aimprime les fichiers normaux et cachés mais pas "." et ".." comme le ls -afont.)


0
tar -czf workspace.tar.gz .??* *

La spécification .??*inclura les fichiers et les répertoires «point» qui ont au moins 2 caractères après le point. L'inconvénient est qu'il n'inclura pas les fichiers / répertoires avec un seul caractère après le point, par exemple .a, s'il y en a.


0

Si l'espace disque n'est pas un problème, cela pourrait également être une chose très facile à faire:

mkdir backup
cp -r ./* backup
tar -zcvf backup.tar.gz ./backup

0

J'ai eu une situation similaire moi-même. Je pense qu'il est préférable de créer le tar ailleurs, puis d'utiliser -C pour indiquer à tar le répertoire de base des fichiers compressés. Exemple:

tar -cjf workspace.tar.gz -C <path_to_workspace> $(ls -A <path_to_workspace>)

De cette façon, il n'est pas nécessaire d'exclure votre propre tarfile. Comme indiqué dans d'autres commentaires, -A listera les fichiers cachés.


0

10 ans plus tard, vous avez une alternative à tar, illustrée avec Git 2.30 (Q1 2021), qui utilise " git archive" ( man ) pour produire l'archive tar de la version au lieu de tar.
(Vous n'avez pas besoin de Git 2.30 pour appliquer cette alternative)

Voir commit 4813277 (11 octobre 2020) et commit 93e7031 (10 octobre 2020) par René Scharfe ( rscharfe) .
(Fusionné par Junio ​​C Hamano - gitster- dans commit 63e5273 , 27 oct 2020)

Makefile: utilisez git init / add / commit / archive pour dist-doc

Signé par: René Scharfe

Réduisez la dépendance aux outils externes en générant les archives de distribution pour la documentation HTML et les pages de manuel en utilisant les commandes ( man ) au lieu de tar. Cela donne aux entrées d'archive les mêmes métadonnées que celles de l'archive dist pour les binaires.git

Donc au lieu de:

tar cf ../archive.tar .

Vous ne pouvez utiliser que Git:

git -C workspace init
git -C workspace add .
git -C workspace commit -m workspace
git -C workspace archive --format=tar --prefix=./ HEAD^{tree} > workspace.tar
rm -Rf workspace/.git

Cela a été initialement proposé car, comme expliqué ici , une plate-forme exotique pourrait avoir une ancienne distribution tar avec des options manquantes.


-1

L'utilisation findest probablement le moyen le plus simple:

find . -maxdepth 1 -exec tar zcvf workspace.tar.gz {} \+

find . -maxdepth 1trouvera tous les fichiers / répertoires / liens symboliques / etc dans le répertoire courant et exécutera la commande spécifiée par -exec. Le {}dans la commande signifie que la liste des fichiers va ici et \+signifie que la commande sera exécutée comme:

tar zcvf workspace.tar.gz .file1 .file2 .dir3

au lieu de

tar zcvf workspace.tar.gz .file1
tar zcvf workspace.tar.gz .file2
tar zcvf workspace.tar.gz .dir3

-J est --xz dans le manuel; combiné avec -c n'est que le début de ce qu'un ordinateur appellera "fun" :)
Ricalsin le

Haha, mon mini-serveur à la maison est plus limité par l'espace disque que par le CPU :) Bon point cependant; Je vais le changer pour utiliser gzip.
Andrew Gunnerson le
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.