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.
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
Vous pouvez utiliser pv pour y parvenir. Pour signaler les progrès correctement, pv
a 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
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
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…
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
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?
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.
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 :)
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:
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
}
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
Méthode basée sur tqdm :
tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null