2013-05-27 2 views
4

J'ai un tableau avec des fichiers et des répertoires que je souhaite ajouter au tar compressé (tar.gz). Au départ, je comptais faire une boucle à travers le réseau et ajouter chaque élément au goudron, quelque chose comme ça:Bash - création de tar pour les éléments du tableau

tar czf my_app.tar.gz 

for app_item in "${app_items[@]}" 
do 
    tar rzf my_app.tar.gz $app_item 
done 

L'exécution du script que j'ai trouvé que je ne peux pas ajouter des fichiers au tar compressé. Je me demandais s'il y avait une autre façon de créer un tar à partir de ma liste de localisation dans le tableau.

Toute aide serait grandement appréciée!

+1

Qu'en est-il de boucler en ajoutant le 'app_item' à une variable et finalement en faisant tar $ that_variable'? – fedorqui

+0

Quelle erreur obtenez-vous? –

+0

Merci @fedorqui, votre solution de contournement fait l'affaire! – alexs333

Répondre

5

Le problème existe uniquement avec les archives compressées. Je propose de créer et d'utiliser d'abord une archive non compressée et de la compresser plus tard lorsque la boucle a été exécutée.

tar cf my_app.tar --files-from /dev/null 
for app_item in "${app_items[@]}" 
do 
    tar rf my_app.tar "$app_item" 
done 
gzip my_app.tar 

Comme @Matthias a souligné dans un commentaire, ce qui crée une archive vide (ce que nous voulons dans la première ligne) est généralement refusée par tar. Pour le forcer à le faire, nous avons besoin d'un truc qui diffère du système d'exploitation du système d'exploitation:

  • BSD: tar cf empty.tar --from-file /dev/null
  • GNU (Linux): tar cvf empty.tar --files-from /dev/null
  • Solaris: tar cvf empty.tar -I /dev/null

Plus de détails à ce sujet explique the page he linked to.

Une approche complètement différente qui semble également fonctionner très bien avec des noms de fichiers avec des espaces en eux (mais pas avec des noms de fichiers avec des sauts de ligne en eux, il est donc pas tout à fait général):

tar cfz my_app.tgz --files-from <(printf "%s\n" "${app_items[@]}") 

Et encore une autre façon de le faire (qui travaille aussi avec des sauts de ligne et d'autres choses dans les noms de fichiers:

eval tar cfz my_app.tgz $(printf "%q " "${app_items[@]}") 

Mais comme d'habitude avec eval vous devez savoir ce que vous passez à lui et que rien de cela provient d'une source non fiable, sinon cela pourrait poser un problème ty question, donc en général, je recommande de l'éviter.

+2

Ou plutôt un seul 'tar rf my_app.tar" $ {app_items [@]} "' sauf si le tableau est gigantesque. – l0b0

+0

Bien sûr. Je pense que l'idée d'itération provient d'une façon ou d'une autre de ne pas pouvoir utiliser le doublage que vous avez donné. (Mais peut-être que l'OP n'y a pas pensé.) – Alfe

+1

'tar: Lâche refusant de créer une archive vide' - résolu en changeant la première ligne en' tar cf my_app.tar --files-from/dev/null' (de [ici] (http://www.wezm.net/technical/2008/03/create-empty-tar-file/)) – Matthias

1

Créez un fichier avec les noms du tableau, puis utilisez l'option -T de tar (BSD ou GNU) pour lire ce fichier. Cela fonctionnera pour n'importe quel nombre de fichiers, travaillera avec des fichiers avec des espaces dans les noms, et compressera pendant l'archivage pour minimiser l'espace disque requis. E.g .:

for ((i = 0; i < ${#app_items[@]}; i++)) 
do 
    echo ${app_items[$i]} >> items$$ 
done 
tar cfz my_app.tar.gz -T items$$ 
rm items$$ 
Questions connexes