Existe alguma maneira de ver qualquer progresso de tar por arquivo?

105

Eu tenho alguns arquivos grandes que gostaria de compactar. Eu posso fazer isso com por exemplo

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

O problema é que não consigo ver nenhum progresso, então não faço ideia de quanto tempo levará ou algo assim. Usando v , posso pelo menos ver quando cada arquivo é concluído, mas quando os arquivos são poucos e grandes, isso não é o mais útil.

Existe uma maneira de obter tar para mostrar um progresso mais detalhado? Como uma porcentagem feita ou uma barra de progresso ou tempo estimado restante ou algo assim. Seja para cada arquivo ou todos eles ou ambos.

    
por Svish 28.07.2010 / 13:51

10 respostas

77

Eu prefiro oneliners assim:

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

Terá saída assim:

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

Para OSX (da resposta 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
    
por 25.10.2013 / 10:15
71

Você pode usar pv para conseguir isso. Para relatar o progresso corretamente, pv precisa saber quantos bytes você está jogando nele. Então, o primeiro passo é calcular o tamanho (em kbyte). Você também pode soltar completamente a barra de progresso e deixar apenas pv informar quantos bytes ela viu; reportaria um 'feito muito e tão rápido'.

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

E então:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2
    
por 28.07.2010 / 14:01
20

melhor barra de progresso ..

apt-get install pv dialog

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

    
por 28.08.2012 / 10:26
10

Confira as opções --checkpoint e --checkpoint-action na página de informações do tar (como para minha distribuição, a descrição para essas opções não está contida na página man → RTFI).

Consulte o link

Com estes (e talvez a funcionalidade de escrever seu próprio comando de ponto de verificação), você pode calcular uma porcentagem…

    
por 04.08.2011 / 22:53
5

Inspirado pela resposta do ajudante

Outra maneira é usar as opções tar 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 "]"

o resultado é como

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

um exemplo completo aqui

    
por 16.07.2017 / 02:22
2

Só notei o comentário sobre o MacOS, e embora eu ache que a solução de @akira (e pv) é muito mais simples, pensei em perseguir um palpite e uma rápida brincadeira na minha caixa MacOS com tar e enviando um sinal SIGINFO. Curiosamente, funcionou :) se você está em um sistema parecido com o BSD, isso deve funcionar, mas em uma caixa do Linux, você pode precisar enviar um SIGUSR1, e / ou tar pode não funciona da mesma maneira.

O lado negativo é que ele fornecerá apenas uma saída (no stdout) mostrando a que distância do arquivo atual ele está, já que acredito que não tenha idéia do tamanho do fluxo de dados que está obtendo.

Então, sim, uma abordagem alternativa seria ativar o tar e periodicamente enviá-lo SIGINFOs a qualquer momento que você quiser saber até onde ele chegou. Como fazer isso?

A abordagem manual ad-hoc

Se você quiser verificar o status em uma base ad-hoc, pode acessar control-T (como Brian Swift mencionou) na janela relevante que enviará o sinal SIGINFO. Um problema com isso é que ele irá enviá-lo para toda a sua cadeia, creio, então se você estiver fazendo:

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

Você também verá o bzip2 informando seu status junto com o 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)

Isso funciona muito bem se você quiser apenas verificar se o tar em execução está parado ou apenas lento. Você provavelmente não precisa se preocupar muito com problemas de formatação neste caso, já que é apenas uma verificação rápida.

O tipo de abordagem automatizada

Se você sabe que vai demorar um pouco, mas quer algo parecido com um indicador de progresso, uma alternativa seria disparar seu processo de tar e em outro terminal trabalhar com o PID e depois lançá-lo em um script que envia repetidamente um sinal acabou. Por exemplo, se você tiver o seguinte scriptlet (e invocá-lo como diz 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?"

Se você invocar dessa maneira, já que você está segmentando apenas tar , você obterá uma saída como esta

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

que eu admito, é meio bonito.

Por último, mas não menos importante - meu script está meio enferrujado, então se alguém quiser entrar e limpar / corrigir / melhorar o código, vá para a sua vida:)

    
por 21.04.2012 / 22:44
2

Inspirado por resposta 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
}

Origem

    
por 18.04.2012 / 03:00
1

Se você souber o número do arquivo em vez do tamanho total de todos eles:

uma alternativa (menos precisa mas adequada) é usar a opção -l e enviar no unix pipe os nomes dos arquivos em vez do conteúdo dos dados.

Vamos ter 12345 arquivos em mydir , o comando é:

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

você pode saber esse valor antecipadamente (por causa do seu caso de uso) ou usar algum comando como find + wc para descobrir:

[myhost@myuser mydir]$ find | wc -l
12345
    
por 15.09.2017 / 14:38
0

Método baseado em tqdm :

tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
    
por 27.04.2018 / 08:44
0

Usando apenas tar

tar tem a opção (desde v1.12) de imprimir informações de status em sinais usando --totals=$SIGNO , por exemplo:

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

As informações de Total bytes written: [...] são impressas em todos os sinais USR1, por exemplo:

pkill -SIGUSR1 tar

Fonte:

por 15.06.2018 / 07:03