Có cách nào để xem bất kỳ tiến trình tar trên mỗi tập tin?


122

Tôi có một vài tệp lớn mà tôi muốn nén. Tôi có thể làm điều này với ví dụ

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

Vấn đề là tôi không thể thấy bất kỳ tiến triển nào, vì vậy tôi không biết phải mất bao lâu hoặc bất cứ điều gì tương tự. Sử dụng vít nhất tôi có thể thấy khi mỗi tệp được hoàn thành, nhưng khi các tệp ít và lớn thì điều này không hữu ích nhất.

Có cách nào để tôi có thể lấy tar để hiển thị tiến độ chi tiết hơn không? Giống như một tỷ lệ phần trăm được thực hiện hoặc một thanh tiến trình hoặc thời gian ước tính còn lại hoặc một cái gì đó. Hoặc cho mỗi tệp duy nhất hoặc tất cả chúng hoặc cả hai.

Câu trả lời:


100

Tôi thích oneliners như thế này:

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

Nó sẽ có đầu ra như thế này:

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

Dành cho OSX (từ câu trả lời của 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
Trên OSX, du không lấy tham số -b, cần phải dự phòng thành: $ ((du -sk / thư mục-với | awk '{print $ 1}') * 1024))
ɾɾɾǝʞ

4
Đẹp, một lót. Bạn có thể giải thích nó được không? Hay nó chỉ hoạt động kỳ diệu bằng cách nào đó?
Kissaki

2
Ok, tôi có nópv $FILE.tgz | tar xzf - -C $DEST_DIR
Krzysztof Szewchot

1
Đối với OS X, tôi cần sử dụng biểu mẫu dấu ngoặc vuông để mở rộng số học, điều này đã tạo ra: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gzKhông có thay đổi này, tôi đã nhận được-bash: syntax error near unexpected token ')'
Dean Becker

1
Lưu ý rằng tiến trình không hiển thị cho đến khi lệnh du kết thúc có thể mất một lúc tùy thuộc vào kích thước, độ phức tạp và phân mảnh của thư mục.
Dậu242

75

Bạn có thể sử dụng pv để đạt được điều này. Để báo cáo tiến trình chính xác, pvcần biết bạn đang ném bao nhiêu byte vào nó. Vì vậy, bước đầu tiên là tính kích thước (tính bằng kbyte). Bạn cũng có thể bỏ hoàn toàn thanh tiến trình và chỉ cho pvbạn biết nó đã thấy bao nhiêu byte; nó sẽ báo cáo "thực hiện rất nhiều và nhanh chóng".

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

Và sau đó:

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

Mát mẻ. pvdường như không đi kèm với Mac OS X, nhưng sẽ dùng thử khi tôi có máy tính có MacPorts. Bạn có thể giải thích những gì bạn đang làm ở đó? Không hoàn toàn chắc chắn những gì dòng đầu tiên làm chính xác.
Svish

4
dòng đầu tiên: tìm nạp thông tin về số lượng byte sẽ được xử lý. dòng thứ hai: sử dụng kích thước từ dòng đầu tiên để cho phép pv hiển thị 'tiến trình'. vì bạn đang truyền dữ liệu, pv không biết sẽ có thêm bao nhiêu byte nữa.
akira

Một bổ sung: SIZE=$(($SIZE * 1000 / 1024))- Tôi không biết liệu đây có phải là một trò chơi trên nền tảng cụ thể của mình hay không, vì vậy tôi không thêm nó vào câu trả lời: dutrả về kích thước trong đó 1 kb = 1024 byte, trong khi pvdường như đang mong đợi 1 kb = 1000 byte. (Tôi đang dùng Ubuntu 10.04)
Izkata

2
@lzkata bạn luôn có thể yêu cầu dusử dụng kích thước khối ưa thích của mình, ví dụ: du -s --block-size=1000hoặc chỉ hoạt động với các byte đơn giản, ví dụ: thả các lệnh kkhỏi dupvcác cuộc gọi. Tuy nhiên, tôi sẽ mong đợi cả hai sử dụng 1024trừ khi được nói khác, ví dụ như --sibật công tắc du, chẳng hạn.
Legolas

1
hoặc chỉ bỏ các công cụ k và chỉ sử dụng các byte đơn giản ( du -sbpv -skhông có bất kỳ công cụ sửa đổi nào). Điều đó sẽ chấm dứt tất cả sự nhầm lẫn.
akira

22

thanh tiến bộ tốt hơn ..

apt-get install pv dialog

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

nhập mô tả hình ảnh ở đây


2
Đây là công việc để trích xuất, nhưng bạn vẫn cần thực hiện một trong những lệnh phức tạp hơn để tạo (đó là câu hỏi ban đầu). Nó vẫn có thể được kết hợp với những cái đó; nó chỉ phức tạp hơn
Daniel H

17

Kiểm tra --checkpoint--checkpoint-actioncác tùy chọn trong trang thông tin tar (như đối với bản phân phối của tôi, mô tả cho các tùy chọn này không có trong trang man → RTFI).

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

Với những điều này (và có thể là chức năng để viết lệnh điểm kiểm tra của riêng bạn), bạn có thể tính được tỷ lệ phần trăm


3
Đây phải là câu trả lời chính xác. Những người khác chỉ cần giải thích các công cụ bổ sung (không được cài đặt theo mặc định, bên cạnh đó) để đạt được một cái gì đó tương tự.
Carmine Giangregorio

@Sardathrion Có lẽ vì nó tarđặc trưng cho GNU .
phk

11

Lấy cảm hứng từ câu trả lời của người trợ giúp

Một cách khác là sử dụng các tartùy chọn gốc

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

kết quả là như thế

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

một ví dụ hoàn chỉnh ở đây


4

Chỉ sử dụng tar

tarcó tùy chọn (kể từ v1.12) để in thông tin trạng thái trên các tín hiệu bằng cách sử dụng --totals=$SIGNO, ví dụ:

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

Các Total bytes written: [...]thông tin được in trên mỗi tín hiệu USR1, ví dụ như:

pkill -SIGUSR1 tar

Nguồn:


3

Chỉ cần chú ý nhận xét về MacOS, và trong khi tôi nghĩ rằng giải pháp từ @akira (và pv) gọn gàng hơn nhiều thì tôi nghĩ tôi sẽ đuổi theo một linh cảm và một cách chơi nhanh trong hộp MacOS của mình bằng tar và gửi tín hiệu SIGINFO. Thật thú vị, nó đã hoạt động :) nếu bạn đang sử dụng hệ thống giống như BSD, thì nó sẽ hoạt động, nhưng trên hộp Linux, bạn có thể cần gửi SIGUSR1 và / hoặc tarcó thể không hoạt động theo cách tương tự.

Mặt trái là nó sẽ chỉ cung cấp cho bạn một đầu ra (trên thiết bị xuất chuẩn) cho bạn thấy tệp đó hiện tại bao xa vì tôi đoán nó không biết luồng dữ liệu mà nó nhận được lớn đến mức nào.

Vì vậy, có, một cách tiếp cận khác là kích hoạt tar và định kỳ gửi SIGINFO bất cứ khi nào bạn muốn biết nó đã đi được bao xa. làm như thế nào?

Cách tiếp cận thủ công, đặc biệt

Nếu bạn muốn có thể kiểm tra trạng thái trên cơ sở đặc biệt, bạn có thể nhấn control-T(như Brian Swift đã đề cập) trong cửa sổ có liên quan sẽ gửi tín hiệu SIGINFO qua. Một vấn đề với nó là nó sẽ gửi nó đến toàn bộ chuỗi của bạn, vì vậy nếu bạn đang làm:

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

Bạn cũng sẽ thấy bzip2 báo cáo trạng thái của nó cùng với 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)

Điều này hoạt động độc đáo nếu bạn chỉ muốn kiểm tra xem tarbạn đang chạy có bị kẹt hay chỉ chậm. Có lẽ bạn không cần phải lo lắng quá nhiều về các vấn đề định dạng trong trường hợp này, vì đó chỉ là một kiểm tra nhanh ..

Cách tiếp cận tự động

Nếu bạn biết rằng sẽ mất một thời gian, nhưng muốn một cái gì đó giống như một chỉ báo tiến trình, một giải pháp thay thế sẽ là loại bỏ quy trình tar của bạn và trong một thiết bị đầu cuối khác xử lý nó và sau đó ném nó vào một tập lệnh liên tục gửi tín hiệu . Ví dụ: nếu bạn có scriptlet sau (và gọi nó như nói 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?"

Nếu bạn gọi nó theo cách này, vì bạn chỉ nhắm mục tiêu, tarbạn sẽ nhận được một đầu ra giống như thế này

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

mà tôi thừa nhận, là khá đẹp.

Cuối cùng nhưng không kém phần quan trọng - kịch bản của tôi hơi bị rỉ sét, vì vậy nếu có ai muốn vào và dọn dẹp / sửa chữa / cải thiện mã, hãy tiếp tục cuộc sống của bạn :)


2
Nếu chạy tartrên dòng lệnh, gõ control-Tsẽ gửi SIGINFO. Nếu đây là một kịch bản thì nó sẽ được thực hiện vớikill -INFO pid
Brian Swift

Hoàn toàn quên mất control-T, tôi rõ ràng đã quen với việc spam quá nhiều cửa sổ giao diện điều khiển vì lợi ích của riêng tôi ..
tanantish

1
tại sao tôi không thể nhìn thấy -SIGINFO khi làmkill -l
Felipe Alvarez

2

Lấy cảm hứng từ câu trả lời của 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
}

Nguồn


17
Một chút bối cảnh và giải thích có thể?
Kissaki

1

Nếu bạn biết số tập tin thay vì tổng kích thước của tất cả chúng:

một cách khác (ít chính xác hơn nhưng phù hợp) là sử dụng tùy chọn -l và gửi trong ống unix tên tệp thay vì nội dung dữ liệu.

Chúng ta hãy có 12345 tệp vào mydir , lệnh là:

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

bạn có thể biết trước giá trị đó (vì trường hợp sử dụng của bạn) hoặc sử dụng một số lệnh như find + wc để khám phá nó:

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

Vì vậy, tại sao không đưa lệnh này vào lệnh phụ? =)
Kirby

tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null. Nó làm việc cho bạn?
Kirby

1

Phương pháp dựa trên tqdm :

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

1

Trên macOS , trước tiên hãy đảm bảo rằng bạn có tất cả các lệnh có sẵn và cài đặt những lệnh còn thiếu (ví dụ pv) bằng cách sử dụng brew .

Nếu bạn chỉ muốn tar mà không nén , hãy đi với:

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

Nếu bạn muốn nén , hãy đi với:

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

Lưu ý: Có thể mất một lúc trước khi thanh tiến trình xuất hiện. Trước tiên hãy thử trên một thư mục nhỏ hơn để đảm bảo nó hoạt động, sau đó chuyển sang thư mục chứa các tệp lớn.


0

Dưới đây là một số con số của bản sao lưu prometheus (dữ liệu số liệu) trên Debian / buster AMD64:

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

Đã hủy công việc này vì không có đủ dung lượng đĩa trống.

Thử nghiệm với zstdtư cách là máy nén để tartheo dõi tiến trình sử dụng 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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.