Existe-t-il un moyen de voir les progrès de tar à l’égard des fichiers?

122

J'ai quelques gros fichiers que j'aimerais compresser. Je peux le faire avec par exemple

tar cvfj big-files.tar.bz2 folder-with-big-files

Le problème est que je ne vois aucun progrès, alors je ne sais pas combien de temps cela va prendre ou quoi que ce soit du genre. En utilisant, vje peux au moins voir quand chaque fichier est terminé, mais lorsque les fichiers sont petits et volumineux, ce n'est pas le plus utile.

Existe-t-il un moyen d'obtenir de la goudron pour afficher des progrès plus détaillés? Par exemple, un pourcentage effectué ou une barre de progression, ou le temps estimé ou quelque chose. Soit pour chaque fichier, soit tous les fichiers, soit les deux.

Svish
la source

Réponses:

100

Je préfère les oneliners comme ceci:

tar cf - /folder-with-big-files -P | pv -s $(du -sb /folder-with-big-files | awk '{print $1}') | gzip > big-files.tar.gz

Il aura une sortie comme ceci:

4.69GB 0:04:50 [16.3MB/s] [==========================>        ] 78% ETA 0:01:21

Pour OSX (d'après la réponse de Kenji)

tar cf - /folder-with-big-files -P | pv -s $(($(du -sk /folder-with-big-files | awk '{print $1}') * 1024)) | gzip > big-files.tar.gz
somme de contrôle
la source
2
Sur OSX, du ne prend pas l'argument -b, il est nécessaire de le replacer à: $ ((du -sk / folder-with | awk '{print $ 1}') * 1024))
mercredi
4
Nice, une ligne. Pouvez-vous l'expliquer? Ou est-ce que ça fonctionne comme par magie?
Kissaki
2
Ok, je l'aipv $FILE.tgz | tar xzf - -C $DEST_DIR
Krzysztof Szewczyk
1
Pour OS X, je devais utiliser la forme de crochet pour l’extension arithmétique, ce qui donnait: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gzSans ce changement, j’obtenais-bash: syntax error near unexpected token ')'
Dean Becker
1
Notez que la progression ne s'affiche pas jusqu'à la fin de la commande du, ce qui peut prendre un certain temps en fonction de la taille, de la complexité et de la fragmentation du répertoire.
Rooster242
75

Vous pouvez utiliser pv pour y parvenir. Pour signaler correctement les progrès, pvvous devez savoir combien d'octets vous lui envoyez. La première étape consiste donc à calculer la taille (en kilo-octets). Vous pouvez également supprimer complètement la barre de progression et laisser simplement pvvous dire combien d'octets il a vus; il signalerait un "fait que beaucoup et que rapide".

% SIZE=`du -sk folder-with-big-files | cut -f 1`

Puis:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2
Akira
la source
Cool. pvne semble pas venir avec Mac OS X, mais va essayer ceci une fois que j'ai un ordinateur avec MacPorts dessus. Pourriez-vous expliquer ce que vous faites là? Pas tout à fait sûr de ce que la première ligne fait exactement.
Samedi
4
première ligne: récupère des informations sur le nombre d'octets qui seront traités. deuxième ligne: utilisez la taille de la première ligne pour permettre à pv de rendre la "progression". étant donné que vous transmettez des données, pv ne sait pas combien d'octets supplémentaires viendront.
akira
Un ajout: SIZE=$(($SIZE * 1000 / 1024))- Je ne sais pas s’il s’agit ou non d’une bizarrerie sur ma plate-forme particulière, je ne l’ajoute donc pas à la réponse: durenvoie la taille où 1 Ko = 1024 octets, alors qu’il pvsemble s’attendre à 1 Ko = 1000 octets. (Je suis sur Ubuntu 10.04)
Izkata
2
@ lzkata vous pouvez toujours demander duà utiliser votre taille de bloc préférée, par exemple du -s --block-size=1000, ou simplement travailler avec des octets en clair, par exemple, en supprimant le ks de l' appel duet pv. Néanmoins, je m'attendrais à ce que les deux utilisent à 1024moins d'indication contraire, par exemple, l' --siactivation du, par exemple.
Legolas
1
ou simplement supprimer le k-stuff et simplement utiliser des octets simples ( du -sbet pv -ssans aucun modificateur). cela devrait mettre fin à toute confusion.
Akira
22

meilleure barre de progression ..

apt-get install pv dialog

(pv -n file.tgz | tar xzf - -C target_directory ) \
2>&1 | dialog --gauge "Extracting file..." 6 50

entrez la description de l'image ici

Mr Noir
la source
2
Cela fonctionne pour l'extraction, mais vous devez toujours exécuter l'une des commandes les plus compliquées pour la création (qui était la question initiale). Il pourrait encore être combiné avec ceux-ci; c'est juste plus compliqué.
Daniel H
17

Consultez les options --checkpointet --checkpoint-actiondans la page d’informations tar (comme pour ma distribution, la description de ces options ne se trouve pas dans la page de manuel → RTFI).

Voir https://www.gnu.org/software/tar/manual/html_section/tar_26.html

Avec ceux-ci (et peut-être la fonctionnalité pour écrire votre propre commande de point de contrôle), vous pouvez calculer un pourcentage…

assistant
la source
3
Cela devrait être la bonne réponse. D'autres expliquent simplement des outils supplémentaires (non installés par défaut) pour atteindre un résultat similaire.
Carmine Giangregorio
@Sardathrion Peut-être parce que c'est tarspécifique à GNU .
phk
11

Inspiré par la réponse de l'assistant

Une autre façon est d'utiliser les taroptions natives

FROMSIZE=`du -sk ${FROMPATH} | cut -f 1`;
CHECKPOINT=`echo ${FROMSIZE}/50 | bc`;
echo "Estimated: [==================================================]";
echo -n "Progess:   [";
tar -c --record-size=1K --checkpoint="${CHECKPOINT}" --checkpoint-action="ttyout=>" -f - "${FROMPATH}" | bzip2 > "${TOFILE}";
echo "]"

le résultat est comme

Estimated: [==================================================]
Progess:   [>>>>>>>>>>>>>>>>>>>>>>>

un exemple complet ici

Campisano
la source
4

Utiliser uniquement du goudron

tara la possibilité (depuis la v1.12) d’imprimer les informations d’état sur les signaux en utilisant --totals=$SIGNO, par exemple:

tar --totals=USR1 -czf output.tar input.file
Total bytes written: 6005319680 (5.6GiB, 23MiB/s)

Les Total bytes written: [...]informations sont imprimées sur chaque signal USR1, par exemple:

pkill -SIGUSR1 tar

La source:

Murmel
la source
3

Je viens de remarquer le commentaire sur MacOS, et même si je pense que la solution de @akira (et pv) est beaucoup plus pratique, je me suis dit que je poursuivrais un pressentiment et une lecture rapide dans ma boîte MacOS avec du goudron et que je lui enverrais un signal SIGINFO. Curieusement, cela a fonctionné :) si vous utilisez un système de type BSD, cela devrait fonctionner, mais sous Linux, vous devrez peut-être envoyer un SIGUSR1 et / ou tarne pas fonctionner de la même manière.

L'inconvénient est qu'il ne vous fournira qu'un résultat (sur stdout) vous indiquant la distance parcourue par le fichier actuel, car je suppose qu'il n'a aucune idée de la taille du flux de données qu'il reçoit.

Donc, oui, une autre approche consisterait à utiliser du goudron et à lui envoyer périodiquement des SIGINFO à tout moment pour savoir dans quelle mesure il se trouve. Comment faire ça?

L'approche ad hoc et manuelle

Si vous voulez pouvoir vérifier le statut sur une base ad-hoc, vous pouvez cliquer control-T(comme mentionné par Brian Swift) dans la fenêtre appropriée qui enverra le signal SIGINFO. Un problème avec cela est qu'il l'enverra à toute votre chaîne, je crois, alors si vous faites:

% tar cvf - folder-with-big-files | bzip2 -c > big-files.tar.bz2

Vous verrez également bzip2 signaler son statut avec tar:

a folder-with-big-files/big-file.imgload 0.79  cmd: bzip2 13325 running 
      14 0.27u 1.02s 

      adding folder-with-big-files/big-file.imgload (17760256 / 32311520)

Cela fonctionne bien si vous voulez juste vérifier si tarvotre course est bloquée ou tout simplement lente. Dans ce cas, vous n'avez probablement pas besoin de trop vous soucier du formatage, car il ne s'agit que d'une vérification rapide.

Le genre d'approche automatisée

Si vous savez que cela va prendre un certain temps, mais que vous souhaitez un indicateur de progression, vous pouvez également lancer votre processus tar et, dans un autre terminal, déterminer son PID, puis l'envoyer dans un script qui envoie à plusieurs reprises un signal. . Par exemple, si vous avez le scriptlet suivant (et l'invoquez par exemple script.sh PID-to-signal interval-to-signal-at):

#!/bin/sh

PID=$1
INTERVAL=$2
SIGNAL=29      # excuse the voodoo, bash gets the translation of SIGINFO, 
               # sh won't..

kill -0 $PID   # invoke a quick check to see if the PID is present AND that
               # you can access it..

echo "this process is $$, sending signal $SIGNAL to $PID every $INTERVAL s"
while [ $? -eq 0 ]; do
     sleep $INTERVAL;
     kill -$SIGNAL $PID;    # The kill signalling must be the last statement
                            # or else the $? conditional test won't work
done
echo "PID $PID no longer accessible, tar finished?"

Si vous l'appelez de cette façon, puisque vous ne ciblez que tarvous obtiendrez une sortie plus semblable à celle-ci.

a folder-with-big-files/tinyfile.1
a folder-with-big-files/tinyfile.2
a folder-with-big-files/tinyfile.3
a folder-with-big-files/bigfile.1
adding folder-with-big-files/bigfile.1 (124612 / 94377241)
adding folder-with-big-files/bigfile.1 (723612 / 94377241)
...

ce que j'avoue, c'est un peu joli.

Dernier point mais non le moindre - mon script est un peu rouillé, donc si quelqu'un veut y aller et nettoyer / corriger / améliorer le code, poursuivez votre vie :)

tanantish
la source
2
Si vous tarle control-Tlancez sur la ligne de commande, le fait de le taper lui enverra un SIGINFO. Si cela était dans un script, ce serait fait aveckill -INFO pid
Brian Swift
Complètement oublié control-T, je me suis clairement habitué à spammer trop de fenêtres de la console pour mon bien ..
tanantish
1
pourquoi je ne peux pas voir -SIGINFO quand je le faiskill -l
Felipe Alvarez le
2

Inspiré par la réponse de Noah Spurrier

function tar {
  local bf so
  so=${*: -1}
  case $(file "$so" | awk '{print$2}') in
  XZ) bf=$(xz -lv "$so" |
    perl -MPOSIX -ane '$.==11 && print ceil $F[5]/50688') ;;
  gzip) bf=$(gzip -l "$so" |
    perl -MPOSIX -ane '$.==2 && print ceil $F[1]/50688') ;;
  directory) bf=$(find "$so" -type f | xargs du -B512 --apparent-size |
    perl -MPOSIX -ane '$bk += $F[0]+1; END {print ceil $bk/100}') ;;
  esac
  command tar "$@" --blocking-factor=$bf \
    --checkpoint-action='ttyout=%u%\r' --checkpoint=1
}

La source

Steven Penny
la source
17
Un peu de contexte et d'explication peut-être?
Kissaki
1

Si vous connaissez le numéro de fichier au lieu de la taille totale de tous:

Une alternative (moins précise mais appropriée) consiste à utiliser l'option -l et à envoyer dans le pipe unix les noms de fichiers au lieu du contenu des données.

Ayons des fichiers 12345 dans mydir , la commande est la suivante:

[myhost@myuser mydir]$ tar cfvz ~/mytarfile.tgz .|pv -s 12345 -l > /dev/null 

vous pouvez connaître cette valeur à l'avance (à cause de votre cas d'utilisation) ou utiliser une commande telle que find + wc pour la découvrir:

[myhost@myuser mydir]$ find | wc -l
12345
bzimage
la source
Alors, pourquoi ne pas mettre cette commande en sous-commande? =)
Kirby
tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. Est-ce que ça marche pour toi?
Kirby
1

Méthode basée sur tqdm :

tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
J_Zar
la source
1

Sous macOS , assurez-vous d’abord que toutes les commandes sont disponibles, puis installez celles qui manquent (par exemple pv) à l’aide de Brew .

Si vous voulez seulement tar sans compression , allez avec:

tar -c folder-with-big-files | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] > folder-with-big-files.tar

Si vous voulez compresser , allez avec:

tar cf - folder-with-big-files -P | pv -s $[$(du -sk folder-with-big-files | awk '{print $1}') * 1024] | gzip > folder-with-big-files.tar.gz

Remarque: la barre de progression peut prendre un certain temps. Commencez par essayer un dossier plus petit pour vous assurer qu'il fonctionne, puis passez au dossier avec des fichiers volumineux.

Bugs Bunny
la source
0

Voici quelques chiffres d’une sauvegarde prometheus (métriques) sur Debian / buster AMD64:

root# cd /path/to/prometheus/
root# tar -cf - ./metrics | ( pv -p --timer --rate --bytes > prometheus-metrics.tar )

Annulé ce travail car il n'y avait pas assez d'espace disque disponible.

Expérimenter avec zstdcomme compresseur pour tarsuivre l’avancement en utilisant pv:

root# apt-get update
root# apt-get install zstd pv

root# tar -c --zstd -f - ./metrics | ( pv -p --timer --rate --bytes > prometheus-metrics.tar.zst )
10.2GiB 0:11:50 [14.7MiB/s]

root# du -s -h prometheus
62G    prometheus

root# du -s -h prometheus-metrics.tar.zst
11G    prometheus-metrics.tar.zst
dileks
la source