linux tar -T - ne fonctionne pas à la volée

3

J'ai trouvé un problème avec linux gnu tar. quand j'utilise l'option

-T -  (for file list from stdin) or
-T named_pipe_file    ,

ça ne marche pas à la volée. par exemple, un script interactif simple:

while read x; do echo $x; done|\
tar cvf tar.tar -T -

tar commence l'archivage uniquement lorsque j'appuie sur ^ D pour marquer l'entrée EOF. La même situation se présente lorsque j'utilise un canal nommé:

mkfifo named_pipe
tar cvf tar.tar -T named_pipe
while read x; do echo $x; done >named_pipe

Il semble que le goudron fasse de la mise en mémoire tampon. Mais c'est combien de temps? Je dois remballer beaucoup de fichiers dans TAR mais avoir peu d’espace disque. Ensuite, je dois le faire à la volée. Je vais utiliser l'option tar --remove-files pour cela. Mais sans interactivité pour l'option -T, c'est impossible. Dans le plan, une partie du code "while" doit décompresser le fichier dans un fichier et attendre que TAR soit supprimé et le fichier suivant. Merci pour les idées :)

ma version de tar: tar (GNU tar) 1.26 (C) 2011 FSF

Znik
la source
Entrez-vous des tarnoms de fichiers ou les données réelles à compresser? L' -Toption attend une liste de noms de fichiers et fonctionne comme annoncé dans une boucle sur mon système.
Terdon le

Réponses:

3

tar est capable d’ajouter à des archives déjà existantes, vous pouvez donc faire:

touch tarfile.tar
command_that_produces_file_list | xargs tar rf tarfile.tar

Malheureusement, cela ne fonctionne pas avec la compression à la volée. Heureusement, le tarformat est assez simple, nous pouvons faire du piratage:

command_that_produces_file_list | {
  xargs -i sh -c 'tar c {} | head -c $(( (`stat --printf="%s" {}` + 511) / 512 * 512 + 512))';
  dd if=/dev/zero bs=512 count=2 2>/dev/null;
} | compression_utility

tarla sortie consiste en, pour chaque fichier, un en-tête de 512 octets suivi de suffisamment de blocs de 512 octets pour contenir les données du fichier. Il ajoute ensuite au moins 2 blocs de zéros de 512 octets. Ce code capture la sortie de la commande tar et supprime les blocs de zéros supplémentaires, combine la sortie des appels multiples effectués tarensemble, puis se colle sur les blocs de zéros terminés. La sortie est envoyée en aval à l'utilitaire de compression, qui s'exécute en même temps que la commande tars.

Wingedsubmariner
la source
Je sais à ce sujet. cela ne peut être fait que pour les archives non compressées ou pour les bandes avec compression hardvare non exposée au logiciel. cette bande est montrée au logiciel comme non compressée. J'ai fait l'exemple aussi simple que possible. Dans le script, j'utilise la compression xz avec les indicateurs -9ev et --remove-files pour tar.
Znik
Vous pouvez essayer de compresser les fichiers sur place, puis de les stocker dans un goudron simple, sinon je trouverais une solution qui n'utilise pas de goudron. Pourquoi avez-vous besoin de faire cela?
wingedsubmariner
@ user215501 Il s'avère qu'il existe un moyen de faire cela avec tar, voir ma réponse récemment modifiée.
wingedsubmariner
@ingedsubmariner, et (à) user215501 très belle mise à jour avec le format tar hack :) J'espère que ce bogue dans tar (à mon avis) sera bientôt supprimé. Je ne sais pas qui de nous fait ce scénario délicat
Znik
@wingedsubmariner chapeau à vous, monsieur! :)
рослав Рахматуллин
2

Bonnes nouvelles. Je reçois la réponse pour mon rapport de bogue à [email protected], cite:

De: Sergey Poznyakoff date:
jeu., 05 septembre 2013 08:40:40 +0300 sujet: Re: [Bug-tar] gnu tar, l'option -T de stdin ou du tube nommé n'est pas interactive

Salut Grzegorz,

Ce problème a été corrigé dans git HEAD (à partir de commit 1fe0c83d).

Cordialement, Sergey

Ensuite, j'attends que cela soit corrigé dans les distributions linux :)

Znik
la source
0

Lisez cette explication (première réponse): Dans quel ordre les commandes piped sont-elles exécutées?

Ce que vous voyez, c’est un blocage de tar pour l’achèvement de la liste d’entrée avant le début du traitement. Faire le traitement en parallèle avec l’entrée, un par un, pourrait être utile, mais je ne pense pas que GNU Tar le supporte.

Je peux seulement deviner que l’attente de la liste complète est terminée afin d’éviter toute complexité dans les "procédures internes" de traitement des arguments en ligne de commande - telles que la procédure à suivre pour "--append and --remove-files". Je pense que la plupart des gens préfèrent supprimer tous les fichiers en masse une fois l’archive terminée, et non à la volée comme il est souhaitable dans ce cas.

Les gens de GNU sont généralement très sympathiques, vous pouvez vous demander pourquoi ce n’est pas une fonctionnalité, comment vous pouvez le faire avec d’autres outils et même demander que cela fasse partie de Tar à l’avenir;

https://lists.gnu.org/mailman/listinfo/help-tar

Рослав Рахматуллин
la source
Malheureusement, ce n'est pas la réponse. vous pouvez remplacer la partie "tar" dans mes exemples par la commande | sed 's / aa / bb /' ou pour les tubes nommés sed / s / aa / bb / '<named_pipe (pour la vérification). cela fonctionne parfaitement. vous mettez par les chaînes du clavier et les phrases "aa" sont remplacées immédiatement si elle est trouvée, et reviennent à l'écran. avec des tuyaux tout va bien. La commande tar est le problème principal.
Znik
C'est ce que j'ai dit, et user215501 a suivi ma suggestion (je pense) avec une bonne nouvelle à la suite;)
рослав Рахматуллин le
Les gens de GNU sont vraiment sympathiques :) Mais à propos de goudron. Cela a la capacité de supprimer les fichiers source immédiatement. Ceci est fait pour économiser de l'espace libre temporaire, décrit chez l'homme. De l’autre côté, les fichiers de l’archive tar ont la même séquence que celle donnée par STDIN pour l’option -T -. En réalité, certains suppriment la mise en mémoire tampon. Ceci ne supprime pas le fichier archivé / terminé en cours, mais le précédent. C'est une prévention contre la perte de données, pas toujours ce travail. Lorsque vous utilisez un algorithme de compression fort avec une mémoire tampon élevée et un dictionnaire élevé, il est fort probable que ce ne sont pas des données enregistrées dans un fichier, mais qu'elles sont toujours conservées dans la mémoire.
Znik