¿Hay alguna forma de ver el progreso del tar por archivo?

122

Tengo un par de archivos grandes que me gustaría comprimir. Puedo hacer esto con, por ejemplo

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

El problema es que no puedo ver ningún progreso, así que no tengo ni idea de cuánto tiempo llevará ni nada de eso. Utilizando val menos puedo ver cuándo se completa cada archivo, pero cuando los archivos son pocos y grandes, esto no es lo más útil.

¿Hay alguna manera de obtener alquitrán para mostrar un progreso más detallado? Como un porcentaje hecho o una barra de progreso o tiempo estimado restante o algo así. Ya sea para cada archivo individual o todos ellos o ambos.

Svish
fuente

Respuestas:

100

Prefiero líneas como esta:

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

Tendrá una salida como esta:

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

Para OSX (de la respuesta 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
suma de comprobación
fuente
2
En OSX, du no toma el argumento -b, necesita retroceder a: $ ((du -sk / folder-with | awk '{print $ 1}') * 1024))
ıɾuǝʞ
44
Bonito, un trazador de líneas. ¿Puedes explicarlo? ¿O simplemente funciona mágicamente de alguna manera?
Kissaki
2
Ok, lo tengopv $FILE.tgz | tar xzf - -C $DEST_DIR
Krzysztof Szewczyk
1
Para OS X, necesitaba usar la forma de corchete para la expansión aritmética, que hizo: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gzSin este cambio, estaba obteniendo-bash: syntax error near unexpected token ')'
Dean Becker el
1
Tenga en cuenta que el progreso no se muestra hasta que finaliza el comando du, lo que puede llevar un tiempo dependiendo del tamaño, la complejidad y la fragmentación del directorio.
Rooster242
75

Puedes usar pv para lograr esto. Para informar el progreso correctamente, pvnecesita saber cuántos bytes le está lanzando. Entonces, el primer paso es calcular el tamaño (en kbytes). También puede soltar por completo la barra de progreso y simplemente pvdecirle cuántos bytes ha visto; informaría un 'hecho tanto y tan rápido'.

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

Y entonces:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2
akira
fuente
Bueno. pvno parece venir con Mac OS X, pero lo probaré una vez que tenga una computadora con MacPorts. ¿Podrías explicar qué estás haciendo allí? No estoy seguro de qué hace exactamente la primera línea.
Svish
44
primera línea: busca información sobre cuántos bytes se manejarán. segunda línea: use el tamaño de la primera línea para permitir que pv muestre 'progreso'. como está canalizando datos, pv no sabe cuántos bytes más vendrán.
akira
Una adición: SIZE=$(($SIZE * 1000 / 1024))- No sé si esto es o no una peculiaridad en mi plataforma en particular, por lo que no lo agrego a la respuesta: dudevuelve el tamaño donde 1 kb = 1024 bytes, mientras pvparece esperar 1 kb = 1000 bytes (Estoy en Ubuntu 10.04)
Izkata
2
@lzkata, siempre puede solicitar el duuso de su tamaño de bloque preferido, por ejemplo du -s --block-size=1000, o simplemente trabajar con bytes simples, por ejemplo, eliminar los k's de las llamadas duy pv. Sin embargo, esperaría que ambos utilicen a 1024menos que se indique lo contrario, por ejemplo, el --siinterruptor encendido du.
Legolas
1
o simplemente suelte el k-stuff y simplemente use bytes simples ( du -sby pv -ssin ningún modificador). eso debería terminar con toda la confusión.
akira
22

mejor barra de progreso ..

apt-get install pv dialog

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

ingrese la descripción de la imagen aquí

El Sr. Black
fuente
2
Esto funciona para la extracción, pero aún necesita hacer uno de los comandos más complicados para la creación (que era la pregunta original). Todavía podría combinarse con esos; Es simplemente más complicado.
Daniel H
17

Consulte las opciones --checkpointy --checkpoint-actionen la página de información de tar (en cuanto a mi distribución, la descripción de estas opciones no está contenida en la página de manual → RTFI).

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

Con estos (y tal vez la funcionalidad para escribir su propio comando de punto de control), puede calcular un porcentaje ...

ayudante
fuente
3
Esta debería ser la respuesta correcta. Otros simplemente explican herramientas adicionales (no instaladas por defecto, además) para lograr algo similar.
Carmine Giangregorio
@Sardathrion Quizás porque es tarespecífico de GNU .
phk
11

Inspirado por la respuesta del ayudante

Otra forma es usar las taropciones nativas

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 "]"

el resultado es como

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

un ejemplo completo aquí

Campisano
fuente
3

Acabo de notar el comentario sobre MacOS, y aunque creo que la solución de @akira (y pv) es mucho más ordenada, pensé en perseguir una corazonada y una solución rápida en mi caja de MacOS con alquitrán y enviarle una señal SIGINFO. Curiosamente, funcionó :) si está en un sistema similar a BSD, esto debería funcionar, pero en una caja de Linux, es posible que deba enviar un SIGUSR1, y / o tarpuede que no funcione de la misma manera.

El inconveniente es que solo le proporcionará una salida (en stdout) que le mostrará qué tan lejos está el archivo actual, ya que supongo que no tiene idea de cuán grande es el flujo de datos que está obteniendo.

Entonces, sí, un enfoque alternativo sería disparar alquitrán y enviarle periódicamente SIGINFO cada vez que desee saber qué tan lejos ha llegado. ¿Como hacer esto?

El enfoque manual ad-hoc

Si desea poder verificar el estado de forma ad-hoc, puede presionar control-T(como mencionó Brian Swift) en la ventana correspondiente que enviará la señal SIGINFO. Un problema con eso es que lo enviará a toda su cadena, creo, así que si está haciendo:

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

También verá que bzip2 informa su estado junto con 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)

Esto funciona bien si solo desea verificar si tarestá ejecutando está atascado, o simplemente lento. Probablemente no necesite preocuparse demasiado por los problemas de formato en este caso, ya que es solo una comprobación rápida.

El tipo de enfoque automatizado

Si sabe que tomará un tiempo, pero desea algo así como un indicador de progreso, una alternativa sería disparar su proceso de tar y en otro terminal resolver su PID y luego lanzarlo a un script que solo envía una señal repetidamente . Por ejemplo, si tiene el siguiente scriptlet (e invoque como se dice 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 lo invoca de esta manera, ya que solo está apuntando tar, obtendrá un resultado más parecido a este

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)
...

lo cual admito, es un poco bonito.

Por último, pero no menos importante: mi scripting está un poco oxidado, así que si alguien quiere entrar y limpiar / arreglar / mejorar el código, vaya por su vida :)

tanantish
fuente
2
Si se ejecuta taren la línea de comando, escribir control-Tle enviará un SIGINFO. Si esto fue en una secuencia de comandos que se haría conkill -INFO pid
Brian Swift
Olvidó por completo control-T, me he acostumbrado claramente con correos no deseados demasiadas ventanas de la consola para mi propio bien ..
tanantish
1
¿por qué no puedo ver -SIGINFO cuando lo hagokill -l
Felipe Alvarez
2

Inspirado por la respuesta 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
}

Fuente

Steven Penny
fuente
17
¿Un poco de contexto y explicación tal vez?
Kissaki
1

Si conoce el número de archivo en lugar del tamaño total de todos ellos:

Una alternativa (menos precisa pero adecuada) es utilizar la opción -l y enviar en la tubería de Unix los nombres de archivo en lugar del contenido de datos.

Tengamos 12345 archivos en mydir , el comando es:

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

puede conocer dicho valor de antemano (debido a su caso de uso) o usar algún comando como find + wc para descubrirlo:

[myhost@myuser mydir]$ find | wc -l
12345
bzimage
fuente
Entonces, ¿por qué no poner este comando en el subcomando? =)
Kirby el
tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. ¿Funciona para ti?
Kirby el
1

Método basado en tqdm :

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

En macOS , primero asegúrese de tener todos los comandos disponibles e instale los que faltan (por ejemplo pv) usando brew .

Si solo quieres tar sin compresión , ve con:

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

Si quieres comprimir , ve con:

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

Nota: Puede pasar un tiempo antes de que aparezca la barra de progreso. Pruebe primero con una carpeta más pequeña para asegurarse de que funciona, luego vaya a la carpeta con archivos grandes.

Bugs Bunny
fuente
0

Aquí hay algunos números de una copia de seguridad prometeus (datos de métrica) en Debian / buster AMD64:

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

Se canceló este trabajo ya que no había suficiente espacio en disco disponible.

Experimentar con un zstdcompresor para tarmonitorear el progreso usando 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
fuente