web-dev-qa-db-fra.com

Existe-t-il un moyen de voir la progression de l'archive tar par fichier?

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 v, je peux au moins voir quand chaque fichier est terminé, mais lorsque les fichiers sont peu volumineux et volumineux, ce n'est pas le plus utile.

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

117
Svish

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
91
checksum

Vous pouvez utiliser pv pour y parvenir. Pour signaler les progrès correctement, pva besoin de 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 pv vous dire combien d'octets il a vus; il rapporterait un "fait que beaucoup et que rapide".

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

Et alors:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2
73
akira

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

enter image description here

22
Mr. Black

Consultez les options --checkpoint et --checkpoint-action dans 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…

15
helper

Inspiré par réponse de l’assistant

Une autre méthode consiste à utiliser les options tar native.

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

8
campisano

Je viens de remarquer le commentaire sur MacOS, et même si je pense que la solution de @akira (et pv) est beaucoup plus facile, j'ai pensé que je chasserais un pressentiment et une lecture rapide dans ma boîte MacOS avec du goudron et l'envoyer un signal SIGINFO. Curieusement, cela a fonctionné :) si vous utilisez un système semblable à BSD, ce devrait fonctionne, mais sur une machine Linux, vous devrez peut-être envoyer un SIGUSR1, et/ou tar pourrait ne pas fonctionner correctement de la même façon.

L'inconvénient est qu'il ne vous fournira qu'une sortie (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 manuelle ad-hoc

Si vous voulez pouvoir vérifier le statut sur une base ad-hoc, vous pouvez cliquer sur control-T (comme l'a mentionné 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 la tar que vous exécutez est bloquée ou tout simplement lente. Dans ce cas, vous n'avez probablement pas besoin de trop vous inquiéter des problèmes de 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 appelez-le sous la forme suivante: 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 tar, vous 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 :)

3
tanantish

Utiliser seulement tar

tar a 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 informations Total bytes written: [...] sont imprimées sur chaque signal USR1, par exemple:

pkill -SIGUSR1 tar

La source:

2
Murmel

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

2
Steven Penny

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
1
bzimage

Méthode basée sur tqdm :

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