題 有沒有辦法看到每個文件的任何tar進度?


我有幾個我要壓縮的大文件。例如,我可以這樣做

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

問題是我看不到任何進展,所以我不知道需要多長時間或類似的東西。運用 v 我至少可以看到每個文件何時完成,但是當文件很少而且很大時,這不是最有用的。

有沒有辦法讓焦油顯示出更詳細的進展?就像完成的百分比或進度條或估計的剩餘時間或某事。每個單個文件或全部文件或兩者。


105
2017-07-28 11:51


起源




答案:


我更喜歡像這樣的oneliners:

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

它將具有如下輸出:

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

對於OSX (來自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

77
2017-10-25 08:15



在OSX上,du不接受-b參數,需要回退到:$((du -sk / folder-with | awk'{print $ 1}')* 1024)) - ıɾuǝʞ
不錯,一個班輪。你能解釋一下嗎?或者它只是神奇地以某種方式工作? - Kissaki
你可以編寫命令來提取上面的tar文件嗎? - Krzysztof Szewczyk
好的,我有它 pv $FILE.tgz | tar xzf - -C $DEST_DIR - Krzysztof Szewczyk
對於OS X,我需要使用方括號形式進行算術擴展,這使得: tar cf - /folder-with-big-files -P | pv -s $[$(du -sk /folder-with-big-files | awk '{print $1}') * 1024] | gzip > big-files.tar.gz 沒有這個改變,我就得到了 -bash: syntax error near unexpected token ')' - Dean Becker


您可以使用 光伏 為達到這個。要正確報告進度, pv需要知道你扔多少字節。因此,第一步是計算大小(以千字節為單位)。您也可以完全刪除進度條,然後讓它 pv 告訴你它看到了多少字節;它會報告“做得那麼多而且那麼快”。

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

然後:

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

71
2017-07-28 12:01



涼。 pv 似乎沒有Mac OS X,但是一旦我有一台裝有MacPorts的電腦就會嘗試這個。你能解釋一下你在那裡做什麼嗎?不太清楚第一行究竟是做什麼的。 - Svish
第一行:獲取有關將處理多少字節的信息。第二行:使用第一行的大小來允許pv渲染'progress'。因為你正在管道數據,所以pv不知道會有多少字節。 - akira
一個補充: SIZE=$(($SIZE * 1000 / 1024))  - 我不知道這是否是我特定平台上的怪癖,所以我不會將其添加到答案中: du 返回大小,其中1 kb = 1024字節,而 pv 似乎期待1 kb = 1000字節。 (我在Ubuntu 10.04上) - Izkata
@lzkata你總能問 du 使用您喜歡的塊大小,例如 du -s --block-size=1000,或只使用普通字節,例如放棄 k來自 du 和 pv 調用。不過,我希望兩者都能使用 1024 除非另有說明,該 --si 打開 du, 例如。 - Legolas
或者只是刪除k-stuff並使用普通字節(du -sb 和 pv -s 沒有任何修飾語)。這應該結束所有的混亂。 - akira


更好的進步吧..

apt-get install pv dialog

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

enter image description here


20
2017-08-28 08:26



這適用於提取,但您仍需要執行一個更複雜的創建命令(這是原始問題)。它仍然可以與那些結合起來;它更複雜。 - Daniel H


看看 --checkpoint 和 --checkpoint-action tar信息頁面中的選項(對於我的發行版,這些選項的描述不包含在手冊頁→RTFI中)。

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

有了這些(也許是編寫自己的checkpoint命令的功能),你可以計算一個百分比......


10
2017-08-04 20:53



這應該是正確的答案。其他人只是解釋額外的工具(除此之外沒有安裝)以實現類似的功能。 - Carmine Giangregorio
@Sardathrion也許是因為它是GNU-tar 具體。 - phk


靈感來自 幫助者的答案

另一種方法是使用原生 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 "]"

結果是這樣的

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

一個完整的例子 這裡


5
2017-07-16 00:22





剛剛注意到關於MacOS的評論,雖然我認為來自@akira(和pv)的解決方案是 許多 neater我以為我會在我的MacOS盒子裡追逐一個預感和一個快速的遊戲,用tar並發送一個SIGINFO信號。有趣的是,它工作:)如果你是一個類似BSD的系統,這個 應該 工作,但在Linux機器上,您可能需要發送SIGUSR1和/或 tar 可能不會以相同的方式工作。

缺點是它只會為你提供一個輸出(在標準輸出上),顯示你當前文件的距離,因為我猜它不知道它獲得的數據流有多大。

所以是的,另一種方法是啟動tar,並在你想知道它到底有多遠的時候定期發送SIGINFO。這該怎麼做?

臨時的,手動的方法

如果您希望能夠在臨時基礎上檢查狀態,則可以點擊 control-T (正如Brian Swift所提到的)在相關窗口中將發送SIGINFO信號。一個問題是它會將它發送到我認為的整個鏈中,所以如果你這樣做:

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

你還會看到bzip2報告它的狀態以及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)

如果你只是想檢查一下,這很好用 tar 你正在跑步被困住,或者只是放慢速度。在這種情況下,您可能不需要過多擔心格式化問題,因為它只是一個快速檢查...

這種自動化方法

如果你知道它需要一段時間,但想要一個像進度指示器,一個替代方案是啟動你的tar進程,在另一個終端解決它的PID,然後把它扔進一個腳本,只是反復發送一個信號。例如,如果您有以下scriptlet(並按照說明調用它) 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?"

如果您以這種方式調用它,因為您只是定位 tar 你會得到更像這樣的輸出

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

我承認,有點漂亮。

最後但並非最不重要 - 我的腳本有點生疏,所以如果有人想進去清理/修復/改進代碼,那就去生活吧:)


2
2018-04-21 20:44



如果跑步 tar 在命令行上,輸入 control-T 會發送一個SIGINFO。如果這是在一個腳本中,它將完成 kill -INFO pid - Brian Swift
完全忘了 control-T,我顯然已經習慣了為自己的好處發送太多控制台窗口的垃圾郵件。 - tanantish
為什麼我不能在做的時候看到-SIGINFO kill -l - Felipe Alvarez


靈感來自 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
}

資源


2
2018-04-18 01:00



可能有一些背景和解釋? - Kissaki