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)

Micha
la source
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.
Jonathan Leffler
la source
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 .
rkhayrov
la source
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 .
Veger
la source
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
empressant
la source
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.

bramp
la source
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 .
caf
la source
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
Peter Jaric
la source
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.

s3v1
la source
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.

Ellis
la source
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.

Loevborg
la source
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.)

Joachim Wagner
la source
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.

Scott Thomson
la source
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
vélo
la source
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.

Ginin
la source
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.

VonC
la source
-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
Andrew Gunnerson
la source
-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