2010-07-28 11:51:37 +0000 2010-07-28 11:51:37 +0000
133
133
Advertisement

Is er een manier om de tar vooruitgang per bestand te zien?

Advertisement

Ik heb een paar grote bestanden die ik zou willen comprimeren. Ik kan dit doen met bijvoorbeeld

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

Het probleem is dat ik geen voortgang kan zien, dus ik heb geen idee hoe lang het zal duren of iets dergelijks. Met behulp van v kan ik tenminste zien wanneer elk bestand klaar is, maar als het om weinig en grote bestanden gaat is dat niet erg handig.

Is er een manier om tar meer gedetailleerde voortgang te laten tonen? Zoals een percentage of een voortgangsbalk of geschatte resterende tijd of zoiets. Hetzij voor elk bestand afzonderlijk, hetzij voor alle bestanden, hetzij voor beide.

Advertisement
Advertisement

Antwoorden (13)

109
109
109
2013-10-25 08:15:15 +0000

Ik geef de voorkeur aan oneliners als deze:

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

Het zal uitvoer hebben zoals dit:

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

Voor OSX (van Kenji’s antwoord)

tar cf - /folder-with-big-files -P | pv -s $(($(du -sk /folder-with-big-files | awk '{print $1}') * 1024)) | gzip > big-files.tar.gz
77
77
77
2010-07-28 12:01:07 +0000

U kunt pv gebruiken om dit te bereiken. Om de voortgang correct te rapporteren, moet pv weten hoeveel bytes je er tegenaan gooit. Dus, de eerste stap is om de grootte te berekenen (in kbyte). Je kunt ook de voortgangsbalk helemaal weglaten en pv gewoon laten vertellen hoeveel bytes het heeft gezien; het zou een ‘zo veel en zo snel gedaan’ rapporteren.

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

En dan:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2
23
Advertisement
23
23
2012-08-28 08:26:14 +0000
Advertisement

betere voortgangsbalk…

apt-get install pv dialog

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

17
17
17
2011-08-04 20:53:06 +0000

Bekijk de --checkpoint en --checkpoint-action opties in de tar info pagina (zoals voor mijn distributie, is de beschrijving voor deze opties niet opgenomen in de man page → RTFI).

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

Met deze (en misschien de functionaliteit om je eigen checkpoint commando te schrijven), kun je een percentage berekenen…

11
Advertisement
11
11
2017-07-16 00:22:25 +0000
Advertisement

Geïnspireerd door helper’s antwoord

Een andere manier is gebruik maken van de native tar opties

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

het resultaat is als

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

een compleet voorbeeld hier

8
8
8
2018-06-15 05:03:41 +0000

Alleen tar gebruiken

tar heeft de optie (sinds v1.12) om statusinformatie af te drukken op signalen die --totals=$SIGNO gebruiken, bijv:

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

De Total bytes written: [...] informatie wordt afgedrukt op elk USR1 signaal, bijv:

pkill -SIGUSR1 tar

Bron:

3
Advertisement
3
3
2012-04-21 20:44:39 +0000
Advertisement

Ik zag net de opmerking over MacOS, en hoewel ik denk dat de oplossing van @akira (en pv) veel netter is, dacht ik een ingeving na te jagen en een snelle playaround in mijn MacOS box met tar en het sturen van een SIGINFO signaal. Grappig genoeg werkte het :) als je op een BSD-achtig systeem zit, zou dit moeten werken, maar op een Linux box moet je misschien een SIGUSR1 sturen, en/of tar werkt misschien niet op dezelfde manier.

Het nadeel is dat het je alleen een output (op stdout) geeft die je laat zien hoe ver het huidige bestand is, omdat ik denk dat het geen idee heeft hoe groot de datastroom is die het binnenhaalt.

Dus ja, een alternatieve aanpak zou zijn om tar te starten en het periodiek SIGINFO’s te sturen op elk moment dat je wilt weten hoe ver het is gekomen. Hoe doe je dat?

De ad-hoc, handmatige aanpak

Als je de status op een ad-hoc basis wilt kunnen controleren, kun je in het betreffende venster op control-T drukken (zoals Brian Swift zei), dat stuurt het SIGINFO signaal door. Een probleem daarbij is dat het naar je hele keten wordt gestuurd, geloof ik, dus als je doet:

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

Je zult ook bzip2 zijn status zien rapporteren samen met 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)

Dit werkt prima als je alleen maar wilt controleren of die tar die je draait vastzit, of gewoon traag is. Je hoeft je waarschijnlijk niet al te veel zorgen te maken over formatteringsproblemen in dit geval, aangezien het slechts een snelle controle is…

De geautomatiseerde aanpak

Als je weet dat het een tijdje gaat duren, maar je wilt toch een soort voortgangsindicator, dan is een alternatief om je tar proces af te vuren en in een andere terminal zijn PID uit te rekenen en die dan in een script te gooien dat herhaaldelijk een signaal verstuurt. Bijvoorbeeld, als je het volgende scriptlet hebt (en het aanroept als bijvoorbeeld 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?"

Als je het op deze manier aanroept, omdat je je alleen op tar richt, krijg je een uitvoer die er meer als volgt uitziet

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

wat, dat geef ik toe, best wel mooi is.

Last but not least - mijn scripting is een beetje roestig, dus als iemand de code wil opkuisen/fixen/verbeteren, ga je gang :)

2
2
2
2012-04-18 01:00:19 +0000

Geïnspireerd door Noah Spurrier’s antwoord

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
}

Bron

1
Advertisement
1
1
2017-09-15 12:38:27 +0000
Advertisement

Als je het bestandsnummer kent in plaats van de totale grootte van alle bestanden:

een alternatief (minder nauwkeurig maar geschikt) is om de -l optie te gebruiken en in de unix pipe de bestandsnamen te sturen in plaats van de gegevensinhoud.

Laten we 12345 bestanden in mydir hebben, het commando is:

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

je kunt zo'n waarde van tevoren weten (vanwege je gebruikssituatie) of een commando als find+wc gebruiken om het te ontdekken:

[myhost@myuser mydir]$ find | wc -l
12345
1
1
1
2019-09-02 20:05:09 +0000

Op macOS , zorg er eerst voor dat je alle commando’s beschikbaar hebt, en installeer de ontbrekende (b.v. pv) met brew .

Als je alleen tar zonder compressie wilt, ga dan met:

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

Als je wilt comprimeren , ga dan met:

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

Opmerking: Het kan even duren voordat de voortgangsbalk verschijnt. Probeer het eerst in een kleinere map om er zeker van te zijn dat het werkt, ga dan naar de map-met-grote-bestanden.

1
1
1
2018-04-27 06:44:10 +0000

Methode gebaseerd op tqdm :

tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
0
0
0
2019-09-13 15:39:11 +0000

Hier zijn wat getallen van een prometheus (metrics data) backup op Debian/buster AMD64:

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

Deze job geannuleerd omdat er niet genoeg disk-ruimte beschikbaar was.

Experimenteren met zstd als compressor voor tar met het monitoren van de voortgang met behulp van 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
0
0
0
2020-02-25 22:54:21 +0000

In mijn dagelijks gebruik hoef ik niet de precieze procentuele voortgang van de bewerking te weten, alleen of hij werkt en (soms) hoeveel hij bijna voltooid is.

Ik los deze behoefte minimaal op door het aantal verwerkte bestanden op een eigen regel weer te geven; in Bash:

let n=0; tar zcvf files.tgz directory | while read LINE; do printf "\r%d" $((n++)) ; done ; echo

Omdat ik dit veel gebruik, heb ik een functie-alias gedefinieerd in . bashrc:

function pvl { declare -i n=0; while read L ; do printf "\r%d" $((++n)) ; done ; echo ; }

Dan gewoon:

tar zcvf files.tgz directory | pvl

Ik kan het aantal bestanden van tevoren berekenen als dat nodig is met find directory | wc -l (Of beter met dezelfde functie als [find directory | pvl] om mijn ongeduld te bedwingen!).

Een ander voorbeeld, rechten instellen voor een virtuele website (daarna is een chown -R snel omdat de bestandsnamen in de cache van het bestandssysteem staan):

find /site -print -type d -exec chmod 2750 "{}" \; -o -type f -exec chmod 640 "{}" | pvl

Het is waar dat deze zijdelingse verwerking de hoofdbewerking zou kunnen vertragen, maar ik denk dat het afdrukken van een return-teken en een paar cijfers niet te duur kan zijn (bovendien voelt het wachten tot het volgende gelijkheidsteken verschijnt of het procentcijfer verandert langzaam aan vergeleken met de subjectieve razendsnelle verandering van cijfers!)

Advertisement

Gerelateerde vragen

10
37
7
14
16
Advertisement
Advertisement