Comment faire fonctionner tar globbing avec l'option «changer de répertoire»

8

J'ai la structure de répertoire suivante:

base/
   files/
   archives/
   scripts/

Je veux un script à exécuter à partir scripts/, les fichiers Compresser qui correspondent results.*.logà files/en gzip tar archive dans archives/.

J'essaie la commande suivante:

tar czfC ../archives/archive.tar.gz ../files results.*.log

Mais je reçois

tar: results.*.log: Cannot stat: No such file or directory
tar: Exiting with failure status due to previous errors

Tandis que

tar czfC ../archives/archive.tar.gz ../files results.a.log

fonctionne comme prévu. Aussi

tar czf ../archives/archive.tar.gz ../files/results.*.log

fonctionne comme je le voudrais, sauf qu'il ajoute le préfixe files/au fichier et émet également un avertissement:

tar: Removing leading `../' from member names

Donc, ma conclusion est que la targlobalisation ne fonctionne pas correctement lorsque vous utilisez l' -Coption. Des conseils sur la façon dont je fais ce travail de manière simple?

Yuval
la source

Réponses:

3

Écrivez-le de manière plus portable:

(cd ../files && tar cf - results.*.log) | 
  gzip -9 > ../archives/archive.tar.gz
Stéphane Chazelas
la source
Le glob sera toujours interprété dans le répertoire courant, avant que cdcela ne se produise.
vonbrand
1
@vonbrand, non, bien sûr que non. &&est comme ;ou newline, il sépare deux commandes. C'est comme dire qu'après l'exécution cd, n'importe quel glob développerait les fichiers dans le répertoire précédent.
Stéphane Chazelas
Tu as raison. On n'a jamais fini d'apprendre.
vonbrand
5

Il n'y a pas de "tar globbing", le globbing se fait par le shell. Et le shell n'a aucune idée de qui tar -C somedirfera son travail somedir, tous les globs sont développés dans le répertoire courant.

vonbrand
la source
En effet, s'il results.a.logexiste dans le répertoire à partir duquel le script est exécuté, cela fonctionne. Mais je ne comprends pas pourquoi cela se produit, car -Csignifie répertoire de changement, donc le répertoire actuel devrait être celui avec results.a.log. Je ne peux pas accepter votre réponse car vous n'offrez pas de solution.
Yuval
2
Le shell prend la commande, étend les globes dans le répertoire courant, fabrique les arguments à partir de ce qui précède et lance le tarprogramme, qui change de répertoire beaucoup plus tard. Impossible de "résoudre" votre problème, désolé. La seule solution consiste à vous déplacer dans le répertoire où vous souhaitez effectuer une globalisation, ou à effectuer la globalisation dans le répertoire et à enregistrer ses résultats dans un fichier ou une variable.
vonbrand
1

Vous pouvez laisser findfaire le globbing et omettre l'option 'change directory' taren supprimant le files/préfixe avant de créer le fichier tar.

L' --no-recursionoption to tarest facultative car aucun répertoire ne sera archivé.

cd base/scripts

# gnutar
# printf '%s\000' ../files/results.*.log |  # find alternative
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   gnutar --transform="s|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
gnutar -tf ../archives/archive.tar.gz | nl
gnutar -xzf ../archives/archive.tar.gz

# bsdtar
find ../files -maxdepth 1 -type f -name "results.*.log" -print0 | 
   bsdtar -s "|^\.\{0,1\}\.\{0,1\}/\{0,1\}files/||" -cf - --null --no-recursion -T - | 
   gzip -9 > ../archives/archive.tar.gz
bsdtar -tf ../archives/archive.tar.gz | nl
bsdtar -xzf ../archives/archive.tar.gz
phron
la source
0

J'ai finalement utilisé

tar czfC ../archives/archive.tar.gz ../files `find ../files/results.*.log -printf "%f\n"`
Yuval
la source
Bien que cela puisse fonctionner pour vous, c'est une façon assez complexe de le faire. De plus, cela ne fonctionnera pas avec les noms de fichiers contenant des caractères spéciaux tels que les espaces. Utilisez l'une des méthodes sensées qui ont été proposées dans les réponses.
Gilles 'SO- arrête d'être méchant'
0

Pour ce faire, écrivez quelque chose comme ceci:

#!/bin/sh

cd ../files
tar zcf ../archives/archive.tar.gz results.*.log
cd ../scripts
vonbrand
la source
0

Ce n'est pas du goudron qui fait le globbing, c'est la coquille. Vous dites d'abord au shell de faire un globbing, puis dites à tar de changer de répertoire. Puisque tar reçoit une liste de noms de fichiers par rapport aux répertoires d'origine, cela ne fonctionne pas.

La solution la plus simple est de loin de laisser le shell changer le répertoire. Interactivement:

cd ../files
tar czf ../archives/archive.tar.gz  results.*.log
cd -

Dans un script:

(
  cd ../files &&
    tar czf ../archives/archive.tar.gz  results.*.log
)

ou

(
  cd ../files &&
    tar czf -  results.*.log
) >../archives/archive.tar.gz
Gilles 'SO- arrête d'être méchant'
la source