web-dev-qa-db-ja.com

ファイルごとにtarの進行状況を確認する方法はありますか?

圧縮したい大きなファイルがいくつかあります。私はこれを行うことができます例えば

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

問題は私が進歩を見ることができないということである、それで私はそれがどれくらいかかるか、またはそのような何かがどのくらいかかるかについての手がかりがない。 vを使うと、少なくとも各ファイルがいつ完成するかを見ることができますが、ファイルが少なくて大きくても、これは最も役に立ちません。

より詳細な進捗状況を示すためにtarを取得する方法はありますか?完了率、進行状況バー、推定残り時間などのようなものです。各単一ファイル、またはそれらすべて、あるいはその両方に対して。

118
Svish

私はこのような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
92
checksum

これを達成するために pv を使うことができます。進行状況を正しく報告するために、pvはあなたがそれに投げているバイト数を知る必要があります。したがって、最初のステップはサイズを計算することです(KB単位)。プログレスバーを完全にドロップして、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
73
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

22
Mr. Black

Tar infoページの--checkpointおよび--checkpoint-actionオプションを調べてください(私のディストリビューションに関しては、これらのオプションの説明はmanページ→RTFIには含まれていません)。

https://www.gnu.org/software/tar/manual/html_section/tar_26.html を参照してください。

これら(そしてあなた自身のチェックポイントコマンドを書く機能)を使えば、パーセンテージを計算できます。

15
helper

ヘルパーの答え からヒントを得た

別の方法はネイティブの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:   [>>>>>>>>>>>>>>>>>>>>>>>

完全な例 はこちら

8
campisano

tarのみを使用する

tarには(v1.12以降)--totals=$SIGNOを使ってシグナルのステータス情報を出力するオプションがあります。

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

Total bytes written: [...]情報はすべてのUSR1シグナルに表示されます。

pkill -SIGUSR1 tar

ソース:

3
Murmel

ちょうどMacOSについてのコメントに気付いた、そして私は@akira(とpv)からの解決策が ずっと より良いと思う間、私はタールで私のMacOSボックスの中で鋭いそして素早い回避策を追いかけてそれにSIGINFOを送ると思った信号。おかしなことに、これはうまくいきました:)もしあなたがBSD風のシステムを使っているなら、これは should で動くでしょうが、LinuxマシンではSIGUSR1を送る必要があり、tarは同じようには動かないでしょう。

欠点は、それが現在のファイルのどこまで進んでいるかを示す出力(stdout)のみを提供することです。これは、データストリームがどれほど大きくなるかについてはわからないからです。

そうです、代替方法としては、tarを起動し、定期的にSIGINFOを送信して、どこまで行ったかを知りたい場合があります。これを行う方法?

アドホックな手動のアプローチ

アドホックベースでステータスをチェックしたい場合は、関連するウィンドウで(Brian Swiftが述べたように)control-Tを押すとSIGINFOシグナルが送信されます。それに関する1つの問題はそれが私が信じているあなたの全体のチェーンにそれを送るということです。

% 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を作成してから、シグナルを繰り返し送信するスクリプトに投入する方法があります。 。たとえば、次のようなスクリプトレットがあるとします(そして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)
...

私が認めるものはちょっとかわいいです。

大事なことを言い忘れましたが - 私のスクリプティングはちょっとさびたので、誰かが入ってコードをクリーンアップ/修正/改善したいのなら、あなたの人生のために行ってください:)

3
tanantish

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
Steven Penny

tqdm に基づく方法:

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

すべてのファイルの合計サイズではなくファイル番号を知っている場合:

別の方法(正確ではありませんが適しています)は、-lオプションを使用して、データコンテンツの代わりにファイル名をunix pipeで送信することです。

12345個のファイルをmydirに入れます。コマンドは次のとおりです。

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

あなたはそのような値を前もって知っているか(あなたのユースケースのために)、またはそれを発見するためにfind + wcのようなコマンドを使うことができます:

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