C'è un modo per vedere eventuali progressi tar per file?


122

Ho un paio di file di grandi dimensioni che vorrei comprimere. Posso farlo con ad esempio

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

Il problema è che non riesco a vedere alcun progresso, quindi non ho idea di quanto tempo ci vorrà o qualcosa del genere. Usando vposso almeno vedere quando ogni file è completato, ma quando i file sono pochi e grandi questo non è il più utile.

C'è un modo per ottenere tar per mostrare progressi più dettagliati? Come una percentuale fatta o una barra di avanzamento o il tempo stimato rimasto o qualcosa del genere. O per ogni singolo file o tutti o entrambi.

Risposte:


100

Preferisco gli oneliner in questo modo:

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

Avrà un output in questo modo:

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

Per OSX (dalla risposta di 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

2
Su OSX, du non accetta argomenti -b, necessari per il fallback a: $ ((du -sk / folder-with | awk '{print $ 1}') * 1024))
ıɾuǝʞ

4
Bello, una fodera. Puoi spiegarlo? O funziona magicamente in qualche modo?
Kissaki,

2
Ok, ce l'hopv $FILE.tgz | tar xzf - -C $DEST_DIR
Krzysztof Szewczyk,

1
Per OS X, dovevo usare la forma della parentesi quadra per l'espansione aritmetica, che faceva: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gzSenza questo cambiamento, stavo ottenendo-bash: syntax error near unexpected token ')'
Dean Becker

1
Si noti che l'avanzamento non viene visualizzato fino al termine del comando du, il che potrebbe richiedere del tempo a seconda delle dimensioni, della complessità e della frammentazione della directory.
Rooster242

75

Puoi usare pv per raggiungere questo obiettivo. Per segnalare lo stato di avanzamento in modo corretto, è pvnecessario sapere quanti byte si stanno lanciando. Quindi, il primo passo è calcolare la dimensione (in kbyte). Puoi anche rilasciare completamente la barra di avanzamento e lasciarti pvdire quanti byte ha visto; segnalerebbe un "fatto tanto e così in fretta".

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

E poi:

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

Freddo. pvnon sembra venire con Mac OS X, ma lo proverò una volta che avrò un computer con MacPorts. Potresti spiegare cosa stai facendo lì? Non sono sicuro di cosa faccia esattamente la prima riga.
Svish,

4
prima riga: recupera informazioni su quanti byte verranno gestiti. seconda riga: utilizzare le dimensioni della prima riga per consentire a pv di eseguire il "progresso". dal momento che si stanno eseguendo il piping dei dati, pv non sa quanti altri byte arriveranno.
Akira,

Un'aggiunta: SIZE=$(($SIZE * 1000 / 1024))- Non so se questa è una stranezza sulla mia piattaforma particolare, quindi non la sto aggiungendo alla risposta: durestituisce dimensioni dove 1 kb = 1024 byte, mentre pvsembra aspettarsi 1 kb = 1000 byte. (Sono su Ubuntu 10.04)
Izkata l'

2
@lzkata si poteva sempre chiedere dudi utilizzare il blocksize preferito, per esempio du -s --block-size=1000, o semplicemente lavorare con byte di pianura, ad esempio cadere la k's dalle due pvchiamate. Ciononostante, mi aspetterei che entrambi usino 1024se non diversamente specificato, ad esempio l' --siaccensione du, ad esempio.
Legolas,

1
oppure rilascia semplicemente k-stuff e usa semplicemente byte semplici ( du -sbe pv -ssenza alcun modificatore). ciò dovrebbe porre fine a tutta la confusione.
Akira,

22

barra di avanzamento migliore ..

apt-get install pv dialog

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

inserisci qui la descrizione dell'immagine


2
Questo funziona per l'estrazione, ma è ancora necessario eseguire uno dei comandi più complicati per la creazione (che era la domanda originale). Potrebbe ancora essere combinato con quelli; è solo più complicato.
Daniel H,

17

Controlla le opzioni --checkpointe --checkpoint-actionnella pagina delle informazioni tar (come per la mia distribuzione, la descrizione di queste opzioni non è contenuta nella pagina man → RTFI).

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

Con questi (e forse la funzionalità per scrivere il tuo comando checkpoint), puoi calcolare una percentuale ...


3
Questa dovrebbe essere la risposta corretta. Altri spiegano semplicemente strumenti extra (non installati di default, inoltre) per ottenere qualcosa di simile.
Carmine Giangregorio,

@Sardathrion Forse perché è tarspecifico per GNU .
phk,

11

Ispirato dalla risposta dell'assistente

Un altro modo è utilizzare le taropzioni 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 "]"

il risultato è come

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

un esempio completo qui



3

Ho appena notato il commento su MacOS, e mentre penso che la soluzione di @akira (e pv) sia molto più ordinata, ho pensato di inseguire un sospetto e un rapido playaround nella mia scatola di MacOS con tar e inviargli un segnale SIGINFO. Stranamente, ha funzionato :) se sei su un sistema simile a BSD, questo dovrebbe funzionare, ma su un box Linux, potresti dover inviare un SIGUSR1 e / o tarpotrebbe non funzionare allo stesso modo.

Il rovescio della medaglia è che ti fornirà solo un output (su stdout) che ti mostra quanto è lontano il file corrente dal momento che immagino che non abbia idea di quanto sia grande il flusso di dati che sta ottenendo.

Quindi sì, un approccio alternativo sarebbe quello di accendere il catrame e inviarlo periodicamente ai SIGINFO ogni volta che vuoi sapere fino a che punto è arrivato. Come fare questo?

L'approccio manuale ad hoc

Se vuoi essere in grado di controllare lo stato su una base ad-hoc, puoi control-Tpremere (come ha detto Brian Swift) nella relativa finestra che invierà il segnale SIGINFO. Un problema con questo è che lo invierà a tutta la tua catena, credo, quindi se stai facendo:

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

Vedrai anche bzip2 segnalare il suo stato insieme a 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)

Funziona bene se vuoi solo controllare se tarstai funzionando è bloccato o solo lento. In questo caso probabilmente non dovrai preoccuparti troppo dei problemi di formattazione, dato che è solo un rapido controllo.

Il tipo di approccio automatizzato

Se sai che ci vorrà un po 'di tempo, ma vuoi qualcosa come un indicatore di progresso, un'alternativa potrebbe essere quella di avviare il tuo processo tar e in un altro terminale risolverlo è PID e poi lanciarlo in uno script che invia ripetutamente un segnale . Ad esempio, se hai il seguente scriptlet (e invocalo come dire 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 lo invochi in questo modo, poiché stai prendendo di mira solo tarotterrai un output più simile a questo

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

che ammetto, è piuttosto carino.

Ultimo ma non meno importante, il mio scripting è un po 'arrugginito, quindi se qualcuno vuole entrare e ripulire / correggere / migliorare il codice, vai per la tua vita :)


2
Se in esecuzione tarsulla riga di comando, digitando control-Tverrà inviato un SIGINFO. Se questo fosse in una sceneggiatura con cui sarebbe fattokill -INFO pid
Brian Swift il

Completamente dimenticato control-T, mi sono chiaramente abituato a inviare spam a troppe finestre della console per il mio bene ..
tanantish

1
perché non riesco a vedere -SIGINFO quando lo facciokill -l
Felipe Alvarez,

2

Ispirato dalla risposta di 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


17
Un piccolo contesto e spiegazione forse?
Kissaki,

1

Se conosci il numero del file anziché la dimensione totale di tutti:

un'alternativa (meno accurata ma adatta) è usare l'opzione -l e inviare nella pipe unix i nomi dei file invece del contenuto dei dati.

Mettiamo 12345 file in mydir , il comando è:

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

puoi conoscere in anticipo tale valore (a causa del tuo caso d'uso) o utilizzare alcuni comandi come find + wc per scoprirlo:

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

Quindi, perché non mettere questo comando in un comando secondario? =)
Kirby

tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. Per te funziona?
Kirby

1

Metodo basato su tqdm :

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

1

Su macOS , assicurati innanzitutto di avere tutti i comandi disponibili e installa quelli mancanti (ad es. pv) Usando brew .

Se vuoi solo tar senza compressione , vai con:

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

Se vuoi comprimere , vai 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: potrebbe essere necessario del tempo prima che venga visualizzata la barra di avanzamento. Prova prima su una cartella più piccola per assicurarti che funzioni, quindi passa a una cartella con file di grandi dimensioni.


0

Ecco alcuni numeri di un backup prometheus (dati metrici) su Debian / buster AMD64:

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

Annullato questo lavoro in quanto lo spazio su disco non era sufficiente.

Sperimentare zstdcome compressore per tarmonitorare il progresso 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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.