Questão Existe uma maneira de ver qualquer progresso de tar por arquivo?


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 eu não vejo nenhum progresso, então eu não tenho idéia de quanto tempo levará ou algo assim. Usando v Eu 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 conseguir 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 único ou todos eles ou ambos.


102


origem




Respostas:


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

74



No OSX, du não aceita o argumento -b, necessário para fallback para: $ ((du -sk / folder-with | awk '{print $ 1}') * 1024)) - ıɾuǝʞ
Nice, um forro. Você pode explicar isso? Ou apenas magicamente funciona de alguma forma? - Kissaki
Você pode escrever o comando para extrair o arquivo tar como acima? - Krzysztof Szewczyk
Ok, eu tenho pv $FILE.tgz | tar xzf - -C $DEST_DIR - Krzysztof Szewczyk
Para o OS X, eu precisava usar o formulário de colchetes para expansão aritmética, o que fez: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gz Sem essa mudança, eu estava ficando -bash: syntax error near unexpected token ')' - Dean Becker


Você pode usar pv Para alcançar isto. Para relatar o progresso corretamente, pvprecisa 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 apenas deixar pv diga quantos bytes ele viu; reportaria um 'feito muito e tão rápido'.

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

E depois:

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

70



Legal. pv não parece vir com o Mac OS X, mas vai tentar fazer isso depois que eu tiver um computador com o MacPorts. Você poderia explicar o que você está fazendo lá? Não tenho certeza do que a primeira linha faz exatamente. - Svish
primeira linha: busca informações sobre quantos bytes serão manipulados. segunda linha: use o tamanho da primeira linha para permitir que pv processe 'progresso'. como você está enviando dados, pv não sabe quantos bytes mais virão. - akira
Um acréscimo: SIZE=$(($SIZE * 1000 / 1024)) - Eu não sei se isso é ou não uma peculiaridade na minha plataforma específica, então não estou adicionando isso à resposta: du retorna o tamanho onde 1 kb = 1024 bytes, enquanto pv parece estar esperando 1 kb = 1000 bytes. (Estou no Ubuntu 10.04) - Izkata
@lzkata você sempre pode perguntar du para usar seu tamanho de bloco preferido, por exemplo du -s --block-size=1000ou apenas trabalhar com bytes simples, por ex. largue o ké do du e pv chamadas. No entanto, eu esperaria que ambos usassem 1024 salvo indicação em contrário, p. a --si ligar du, por exemplo. - Legolas
ou simplesmente solte os k-stuff e use apenas bytes simples (du -sb e pv -ssem qualquer modificador). isso deve acabar com toda a confusão. - akira


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

enter image description here


20



Isso funciona para extração, mas você ainda precisa fazer um dos comandos mais complicados para criação (que era a pergunta original). Ainda poderia ser combinado com aqueles; é apenas mais complicado. - Daniel H


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

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

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


10



Esta deve ser a resposta correta. Outros apenas explicam ferramentas extras (não instaladas por padrão, além disso) para conseguir algo similar. - Carmine Giangregorio
@Sardathrion Talvez porque é GNU-tar específico. - phk


Inspirado por resposta do ajudante

Outra maneira é usar o nativo tar opções

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


5





Apenas notei o comentário sobre o MacOS, e embora eu ache que a solução de @akira (e pv) é Muito de mais limpo Eu pensei em perseguir um palpite e uma rápida brincadeira na minha caixa MacOS com tar e enviar um sinal SIGINFO. Curiosamente, funcionou :) se você estiver em um sistema semelhante ao BSD, devemos trabalho, mas em uma caixa Linux, você pode precisar enviar um SIGUSR1, e / ou tar pode não funcionar da mesma maneira.

O lado negativo é que ele só irá fornecer-lhe uma saída (em stdout) mostrando-lhe o quão longe o arquivo atual é, pois eu estou supondo que não tem idéia sobre o quão grande é o fluxo de dados que está recebendo.

Então, sim, uma abordagem alternativa seria disparar o tar e enviá-lo periodicamente a SIGINFOs sempre que 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 atingir 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 eu acredito, então se você estiver fazendo:

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

Você também verá o bzip2 reportando 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 tar você está correndo está preso, 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 o seu processo de tar e em outro terminal resolver o seu PID e depois jogá-lo em um script que envia repetidamente um sinal . Por exemplo, se você tiver o seguinte scriptlet (e invocá-lo como dizer 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 desta maneira, desde que você está alvejando apenas tar você terá uma saída mais parecida com isso

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 - o meu script está meio enferrujado, por isso, se alguém quiser entrar e limpar / corrigir / melhorar o código, vá para a sua vida :)


2



Se correndo tar na linha de comando, digitando control-T irá enviar um SIGINFO. Se isso estivesse em um roteiro, seria feito com kill -INFO pid - Brian Swift
Esqueci completamente control-T, Eu claramente me acostumei a spam muitas janelas do console para o meu bem .. - tanantish
por que não consigo ver -SIGINFO ao fazer kill -l - Felipe Alvarez


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

Fonte


2



Um pouco de contexto e explicação talvez? - Kissaki


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 encontrar + wc para descobrir:

[myhost@myuser mydir]$ find | wc -l
12345

1



Então, por que não colocar esse comando no subcomando? =) - Kirby
tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. Funciona para você? - Kirby


Método baseado em tqdm:

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

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)

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

pkill -SIGUSR1 tar

Fonte:


0