Apakah ada cara untuk melihat progres tar per file?

122

Saya punya beberapa file besar yang ingin saya kompres. Saya bisa melakukan ini dengan misalnya

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

Masalahnya adalah saya tidak bisa melihat kemajuan, jadi saya tidak tahu berapa lama waktu yang dibutuhkan atau hal-hal seperti itu. Menggunakan vI setidaknya dapat melihat kapan setiap file selesai, tetapi ketika file sedikit dan besar ini bukan yang paling membantu.

Apakah ada cara agar tar bisa menunjukkan kemajuan yang lebih rinci? Seperti persentase yang dilakukan atau bilah kemajuan atau perkiraan waktu tersisa atau sesuatu. Baik untuk setiap file tunggal atau semuanya atau keduanya.

Svish
sumber

Jawaban:

100

Saya lebih suka oneliners seperti ini:

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

Ini akan memiliki output seperti ini:

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

Untuk OSX (dari jawaban 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
checksum
sumber
2
Pada OSX, du tidak mengambil argumen -b, harus mundur ke: $ ((du -sk / folder-with | awk '{print $ 1}') * 1024))
ıɾuǝʞ
4
Bagus, satu liner. Bisakah Anda menjelaskannya? Atau apakah itu hanya berfungsi secara ajaib?
Kissaki
2
Oke, saya punyapv $FILE.tgz | tar xzf - -C $DEST_DIR
Krzysztof Szewczyk
1
Untuk OS X, saya perlu menggunakan bentuk kurung siku untuk ekspansi aritmatika, yang membuat: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gzTanpa perubahan ini, saya dapat-bash: syntax error near unexpected token ')'
Dean Becker
1
Perhatikan bahwa progres tidak muncul sampai perintah du selesai yang bisa memakan waktu cukup lama tergantung pada ukuran, kompleksitas, dan fragmentasi direktori.
Rooster242
75

Anda dapat menggunakan pv untuk mencapai ini. Untuk melaporkan kemajuan dengan benar, pvperlu tahu berapa byte yang Anda lemparkan. Jadi, langkah pertama adalah menghitung ukuran (dalam kbyte). Anda juga dapat menghapus bilah kemajuan sepenuhnya dan biarkan pvAnda tahu berapa banyak byte yang telah dilihatnya; itu akan melaporkan 'melakukan yang banyak dan secepat itu'.

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

Lalu:

% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \ 
     bzip2 -c > big-files.tar.bz2
akira
sumber
Keren. pvtampaknya tidak datang dengan Mac OS X, tetapi akan mencoba ini setelah saya memiliki komputer dengan MacPort di atasnya. Bisakah Anda menjelaskan apa yang Anda lakukan di sana? Tidak yakin persis apa yang dilakukan baris pertama.
Svish
4
baris pertama: ambil info tentang berapa byte yang akan ditangani. baris kedua: gunakan ukuran dari baris pertama untuk memungkinkan pv membuat 'progres'. karena Anda memipihkan data, pv tidak tahu berapa banyak lagi byte yang akan datang.
akira
Satu tambahan: SIZE=$(($SIZE * 1000 / 1024))- Saya tidak tahu apakah ini kekhasan pada platform khusus saya, jadi saya tidak menambahkannya ke jawaban: dumengembalikan ukuran di mana 1 kb = 1024 byte, sementara pvtampaknya mengharapkan 1 kb = 1000 byte. (Saya di Ubuntu 10,04)
Izkata
2
@ lzkata Anda selalu dapat meminta duuntuk menggunakan blocksize pilihan Anda, mis. du -s --block-size=1000, atau hanya bekerja dengan byte biasa, misalkan drop kdari dudan pvpanggilan. Namun demikian, saya akan mengharapkan keduanya untuk digunakan 1024kecuali jika diberitahu sebaliknya, mis. --siMenyalakan du, misalnya.
Legolas
1
atau cukup jatuhkan k-stuff dan gunakan byte polos ( du -sbdan pv -stanpa pengubah). yang seharusnya mengakhiri semua kebingungan.
akira
22

progress bar lebih baik ..

apt-get install pv dialog

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

masukkan deskripsi gambar di sini

Tuan hitam
sumber
2
Ini berfungsi untuk ekstraksi, tetapi Anda masih perlu melakukan salah satu perintah yang lebih rumit untuk pembuatan (yang merupakan pertanyaan asli). Itu masih bisa digabungkan dengan itu; itu lebih rumit.
Daniel H
17

Lihat --checkpointdan --checkpoint-actionopsi di halaman info tar (seperti untuk distribusi saya, deskripsi untuk opsi ini tidak terdapat di halaman manual → RTFI).

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

Dengan ini (dan mungkin fungsionalitas untuk menulis perintah pos pemeriksaan Anda sendiri), Anda dapat menghitung persentase ...

pembantu
sumber
3
Ini seharusnya jawaban yang benar. Lainnya hanya menjelaskan alat tambahan (tidak diinstal secara default, selain itu) untuk mencapai sesuatu yang serupa.
Carmine Giangregorio
@Sardathrion Mungkin karena tarspesifik GNU .
phk
11

Terinspirasi oleh jawaban pembantu

Cara lain adalah menggunakan taropsi asli

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

hasilnya seperti

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

contoh lengkap di sini

campisano
sumber
4

Hanya menggunakan tar

tarmemiliki opsi (sejak v1.12) untuk mencetak informasi status pada sinyal menggunakan --totals=$SIGNO, misalnya:

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

The Total bytes written: [...]informasi akan dicetak pada setiap sinyal USR1, misalnya:

pkill -SIGUSR1 tar

Sumber:

Murmel
sumber
3

Hanya memperhatikan komentar tentang MacOS, dan sementara saya pikir solusi dari @akira (dan pv) jauh lebih rapi saya pikir saya akan mengejar firasat dan playaround cepat di kotak MacOS saya dengan tar dan mengirimkannya sinyal SIGINFO. Lucunya, itu berhasil :) jika Anda menggunakan sistem mirip-BSD, ini seharusnya bekerja, tetapi pada kotak Linux, Anda mungkin perlu mengirim SIGUSR1, dan / atau tarmungkin tidak bekerja dengan cara yang sama.

Sisi buruknya adalah ia hanya akan memberi Anda output (on stdout) yang menunjukkan seberapa jauh file saat ini karena saya kira tidak tahu seberapa besar aliran data yang didapat.

Jadi ya, pendekatan alternatif adalah menjalankan tar dan secara berkala mengirimkannya SIGINFO kapan pun Anda ingin tahu seberapa jauh jaraknya. Bagaimana cara melakukannya?

Ad-hoc, pendekatan manual

Jika Anda ingin dapat memeriksa status berdasarkan ad-hoc, Anda dapat menekan control-T(seperti yang disebutkan Brian Swift) di jendela yang relevan yang akan mengirimkan sinyal SIGINFO. Satu masalah dengan itu adalah itu akan mengirimkannya ke seluruh rantai Anda, saya percaya, jadi jika Anda melakukannya:

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

Anda juga akan melihat bzip2 melaporkan statusnya bersama dengan 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)

Ini berfungsi baik jika Anda hanya ingin memeriksa apakah tarAnda sedang berjalan macet, atau hanya lambat. Anda mungkin tidak perlu terlalu khawatir tentang memformat masalah dalam kasus ini, karena ini hanya pemeriksaan cepat ..

Jenis pendekatan otomatis

Jika Anda tahu itu akan memakan waktu, tetapi ingin sesuatu seperti indikator kemajuan, alternatifnya adalah menjalankan proses tar Anda dan di terminal lain berhasil PID dan kemudian membuangnya ke dalam skrip yang baru saja mengirim sinyal berulang kali . Misalnya, jika Anda memiliki skrip berikut (dan aktifkan seperti kata 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?"

Jika Anda memintanya seperti ini, karena Anda hanya menargetkan, tarAnda akan mendapatkan hasil lebih seperti ini

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

yang saya akui, agak cantik.

Last but not least - skrip saya agak berkarat, jadi jika ada yang ingin masuk dan membersihkan / memperbaiki / meningkatkan kode, pergi untuk hidup Anda :)

cokelat
sumber
2
Jika berjalan tardi baris perintah, mengetik control-Takan mengirimkannya SIGINFO. Jika ini dalam naskah, itu akan dilakukan dengankill -INFO pid
Brian Swift
Benar-benar lupa control-T, saya jelas sudah terbiasa dengan spamming terlalu banyak jendela konsol untuk kebaikan saya sendiri ..
tanantish
1
mengapa saya tidak bisa melihat -SIGINFO ketika melakukankill -l
Felipe Alvarez
2

Terinspirasi oleh jawaban 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
}

Sumber

Steven Penny
sumber
17
Mungkin sedikit konteks dan penjelasannya?
Kissaki
1

Jika Anda tahu nomor file alih-alih ukuran total dari semuanya:

alternatif (kurang akurat tetapi cocok) adalah dengan menggunakan opsi -l dan mengirim pipa unix nama file, bukan konten data.

Mari kita memiliki 12345 file ke mydir , perintahnya adalah:

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

Anda dapat mengetahui nilai tersebut di muka (karena kasus penggunaan Anda) atau menggunakan beberapa perintah seperti find + wc untuk menemukannya:

[myhost@myuser mydir]$ find | wc -l
12345
bzimage
sumber
Jadi, mengapa tidak memasukkan perintah ini ke dalam sub-perintah? =)
Kirby
tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. Apakah itu berhasil untuk Anda?
Kirby
1

Metode berdasarkan tqdm :

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

Pada macOS , pertama pastikan bahwa Anda memiliki semua perintah yang tersedia, dan instal yang hilang (misalnya pv) menggunakan minuman .

Jika Anda hanya ingin tar tanpa kompresi , lanjutkan dengan:

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

Jika Anda ingin mengompres , lanjutkan dengan:

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

Catatan: Mungkin diperlukan beberapa saat sebelum bilah kemajuan muncul. Cobalah folder yang lebih kecil terlebih dahulu untuk memastikannya berfungsi, lalu pindah ke folder-dengan-file-besar.

Bugs Bunny
sumber
0

Berikut adalah beberapa nomor cadangan prometheus (data metrik) pada Debian / buster AMD64:

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

Membatalkan pekerjaan ini karena tidak ada ruang disk yang cukup.

Bereksperimen dengan zstdsebagai kompresor untuk tarmemantau kemajuan menggunakan 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
dileks
sumber