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

Czy istnieje sposób, aby zobaczyć postęp tarowania dla każdego pliku?

Advertisement

Mam kilka dużych plików, które chciałbym skompresować. Mogę to zrobić używając np.

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

Problem w tym, że nie widzę żadnego postępu, więc nie mam pojęcia jak długo to potrwa, ani nic takiego. Używając v mogę przynajmniej zobaczyć, kiedy każdy plik jest ukończony, ale kiedy plików jest mało i są duże, nie jest to najbardziej pomocne.

Czy istnieje sposób, w jaki mogę sprawić, by tar pokazywał bardziej szczegółowy postęp? Na przykład procent wykonanego zadania, pasek postępu, szacowany czas pozostały do końca lub coś w tym stylu. Albo dla każdego pojedynczego pliku, albo dla wszystkich, albo dla obu.

Advertisement
Advertisement

Odpowiedzi (13)

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

Wolę takie onelinery jak ten:

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

To będzie miało wyjście jak to:

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

Dla OSX (z odpowiedzi Kenji'ego)

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

Możesz użyć pv aby to osiągnąć. Aby poprawnie raportować postęp, pv musi wiedzieć, ile bajtów mu rzucasz. Tak więc, pierwszym krokiem jest obliczenie rozmiaru (w kbajtach). Możesz również całkowicie zrezygnować z paska postępu i pozwolić pv powiedzieć, ile bajtów widział; zgłosiłby on “zrobione tyle i tak szybko”.

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

A potem:

% 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

lepszy pasek postępu…

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

Sprawdź opcje --checkpoint i --checkpoint-action na stronie informacyjnej tar (w mojej dystrybucji opis tych opcji nie jest zawarty na stronie man → RTFI).

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

Mając je (i być może funkcjonalność do napisania własnego polecenia checkpoint), możesz obliczyć procent…

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

Zainspirowany odpowiedzią helpera

Innym sposobem jest użycie natywnych opcji tar

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

wynik jest jak

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

pełny przykład tutaj

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

Używając tylko tar

tar posiada opcję (od v1.12) drukowania informacji o stanie sygnałów używających --totals=$SIGNO, np:

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

Informacja Total bytes written: [...] jest drukowana na każdym sygnale USR1, np:

pkill -SIGUSR1 tar

Źródło:

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

Właśnie zauważyłem komentarz o MacOS, i chociaż myślę, że rozwiązanie od @akira (i pv) jest dużo zgrabniejsze, pomyślałem, że będę ścigał przeczucie i szybkie playaround w moim pudełku MacOS z tar i wysyłając mu sygnał SIGINFO. Co zabawne, zadziałało :) jeśli jesteś na systemie podobnym do BSD, to powinno zadziałać, ale na Linuksie, możesz potrzebować wysłać SIGUSR1, i/lub tar może nie działać w ten sam sposób.

Minusem jest to, że dostarczy ci tylko wyjście (na stdout) pokazujące jak daleko w bieżącym pliku jest, ponieważ zgaduję, że nie ma pojęcia o tym, jak duży jest strumień danych, który dostaje.

Więc tak, alternatywnym podejściem byłoby odpalenie tar'a i okresowe wysyłanie mu SIGINFO za każdym razem, gdy chcesz wiedzieć jak daleko zaszedł. Jak to zrobić?

Podejście ręczne, ad-hoc

Jeśli chcesz mieć możliwość sprawdzania stanu ad-hoc, możesz uderzyć control-T (jak wspomniał Brian Swift) w odpowiednim oknie, co spowoduje wysłanie sygnału SIGINFO. Jednym problemem z tym jest to, że wyśle go do całego łańcucha, jak sądzę, więc jeśli robisz:

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

zobaczysz również, że bzip2 zgłasza swój status razem z 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)

To działa ładnie, jeśli chcesz tylko sprawdzić, czy ten tar, który uruchamiasz, utknął, czy po prostu jest powolny. Prawdopodobnie nie musisz się zbytnio martwić o kwestie formatowania w tym przypadku, ponieważ jest to tylko szybkie sprawdzenie.

Rodzaj zautomatyzowanego podejścia

Jeśli wiesz, że zajmie to trochę czasu, ale chcesz mieć coś w rodzaju wskaźnika postępu, alternatywą byłoby odpalenie procesu tar i w innym terminalu ustalenie jego PID, a następnie wrzucenie go do skryptu, który po prostu wielokrotnie wysyła sygnał. Na przykład, jeśli masz następujący skrypt (i wywołujesz go jako powiedzmy 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?"

Jeśli wywołasz go w ten sposób, ponieważ celujesz tylko w tar, otrzymasz wyjście bardziej zbliżone do tego

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

co, przyznaję, jest całkiem ładne.

Last but not least - moje skrypty są trochę zardzewiałe, więc jeśli ktoś chce się zabrać za czyszczenie/poprawianie/ulepszanie kodu, to proszę bardzo :)

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

Zainspirowany przez Odpowiedź 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
}

Źródło

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

Gdybyś znał numery plików zamiast ich łącznego rozmiaru:

alternatywą (mniej dokładną, ale odpowiednią) jest użycie opcji -l i wysłanie do potoku unixowego nazw plików zamiast zawartości danych.

Miejmy 12345 plików w mydir, polecenie brzmi:

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

Możesz znać taką wartość z góry (ze względu na swój przypadek użycia) lub użyć komendy takiej jak find+wc aby ją odkryć:

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

Na macOS , najpierw upewnij się, że masz wszystkie dostępne polecenia i zainstaluj brakujące (np. pv) używając brew .

Jeśli chcesz tylko tar bez kompresji, wybierz:

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

Jeśli chcesz kompresować , idź z:

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

Uwaga: Może chwilę potrwać, zanim pojawi się pasek postępu. Spróbuj najpierw na mniejszym folderze, aby upewnić się, że działa, a następnie przenieś się do folderu z dużymi plikami.

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

Metoda oparta na 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

Oto kilka liczb z backupu prometeusza (dane metryczne) na Debianie/busterze AMD64:

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

Anulowano zadanie, ponieważ nie było wystarczająco dużo miejsca na dysku.

Eksperymentuję z zstd jako kompresorem dla tar z monitorowaniem postępu przy użyciu 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

W moim codziennym użytkowaniu nie potrzebuję znać dokładnego procentowego postępu operacji, a jedynie to, czy działa i (czasami) jak bardzo jest bliska zakończenia.

Rozwiązuję tę potrzebę minimalnie, pokazując liczbę przetworzonych plików w osobnej linii; w Bashu:

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

Ponieważ często tego używam, zdefiniowałem alias funkcji w . bashrc:

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

Wtedy po prostu:

tar zcvf files.tgz directory | pvl

Mogę obliczyć liczbę plików z wyprzedzeniem, jeśli jest to potrzebne, używając find directory | wc -l (lub lepiej używając tej samej funkcji pokazanej [find directory | pvl], aby zgasić moją niecierpliwość!).

Inny przykład, ustawianie praw dla wirtualnej strony (po tym, chown -R jest szybkie, ponieważ nazwy plików są w pamięci podręcznej systemu plików):

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

To prawda, że to przetwarzanie boczne może spowolnić główną operację, ale myślę, że drukowanie znaku powrotu i kilku cyfr nie może być zbyt kosztowne (poza tym oczekiwanie na pojawienie się następnego znaku równości lub zmianę cyfry procentowej czuje się powolne w porównaniu z subiektywną płonącą szybkością zmiany cyfr!).

Advertisement

Pytania pokrewne

10
37
7
14
6
Advertisement
Advertisement