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


122

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

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

問題は、進行状況が見えないことです。そのため、どのくらい時間がかかるかなどはわかりません。を使用するvと、少なくとも各ファイルがいつ完了するかを確認できますが、ファイルが少なくて大きい場合、これはあまり役に立ちません。

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

回答:


100

私はこのような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の場合(ケンジの回答より)

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
OSXでは、duは-b引数を取りません。フォールバックするために必要です:$((du -sk / folder-with | awk '{print $ 1}')* 1024))
ıɾuǝʞ13年

4
ニース、ワンライナー。説明できますか?それとも、魔法のように機能するのでしょうか?
キサキ14年

2
わかりました、私はそれを持っていますpv $FILE.tgz | tar xzf - -C $DEST_DIR
クシシュトフシェフチク14年

1
: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 ')'
ディーン・ベッカー

1
ディレクトリのサイズ、複雑さ、断片化に応じて時間がかかるduコマンドが完了するまで、進行状況は表示されないことに注意してください。
Rooster242

75

これを実現するには、pvを使用できます。進行状況を正しく報告するには、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

クール。pvMac OS Xには付属していないようですが、MacPortsが搭載されたコンピューターがあれば、これを試してみます。あなたはそこで何をしているのか説明してもらえますか?最初の行が正確に何をするかはよくわかりません。
Svish

4
1行目:処理されるバイト数に関する情報を取得します。2行目:最初の行のサイズを使用して、pvが「進行状況」をレンダリングできるようにします。データをパイピングしているため、pvはあと何バイト来るかわかりません。
アキラ

1つの追加:SIZE=$(($SIZE * 1000 / 1024))-これが私の特定のプラットフォームの癖であるかどうかわからないので、答えに追加していません: du1 kb = 1024バイトのサイズを返しますが、pv1 kb = 1000を期待しているようですバイト。(私はUbuntu 10.04を使用しています)
Izkata

2
@lzkataいつでも求めることができるduなど、お好みのブロックサイズを使用するようにdu -s --block-size=1000、あるいは単なるバイトで動作する、例えばドロップkから年代をduしてpv呼び出し。それにもかかわらず、1024たとえば--siスイッチオンduなど、特に指示がない限り、両方を使用することを期待します。
レゴラス

1
または、単にk-stuffをドロップして、プレーンバイトを使用します(du -sbおよびpv -s修飾子なし)。これですべての混乱が終わります。
アキラ

22

より良いプログレスバー

apt-get install pv dialog

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

ここに画像の説明を入力してください


2
これは抽出には有効ですが、作成にはもっと複雑なコマンドを実行する必要があります(元の質問です)。それでもそれらと組み合わせることができます。もっと複雑です。
ダニエルH 14

17

tar情報ページのオプション--checkpoint--checkpoint-actionオプションを確認してください(私の配布に関しては、これらのオプションの説明はmanページ→RTFIには含まれていません)。

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

これら(およびおそらく独自のチェックポイントコマンドを作成する機能)を使用すると、パーセンテージを計算できます…


3
これが正解です。他の人は、同様のことを達成するための追加のツール(デフォルトではインストールされません)を説明するだけです。
カーマインジャングレゴリオ

@Sardathrion多分それはGNU tar固有だからでしょう。
phk

11

ヘルパーの答えに触発

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

ここに完全な例


4

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

ただ、MacOSのについてのコメントを気づいた、と私は@akira(およびPV)からの解決策を考えている間されてずっとすっきり私は勘とタールと私のMacOSのボックス内の迅速なplayaroundを追いかけ、それにSIGINFO信号を送信しようと思いました。おもしろいことに、それは動作しました:) BSDのようなシステムを使用している場合、これ動作するはずですが、Linuxボックスでは、SIGUSR1を送信する必要tarがあるかもしれません。

欠点は、取得するデータストリームの大きさがわからないと推測しているため、現在のファイルがどれだけ遠くにあるかを示す出力(stdout)のみを提供することです。

そのため、別の方法として、tarを起動し、どこまで到達したかを知りたいときにSIGINFOを定期的に送信します。これを行う方法?

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

アドホックベースでステータスを確認したい場合control-Tは、関連するウィンドウで(Brian Swiftが述べたように)ヒットすると、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を処理してから、繰り返しシグナルを送信するスクリプトにスローする方法があります。 。たとえば、次のスクリプトレットがある場合(およびsayとして呼び出す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
tarコマンドラインで実行している場合、入力control-TするとSIGINFOが送信されます。このスクリプトにあった場合、それはで行われることになるkill -INFO pid
ブライアン・スウィフト

完全に忘れてcontrol-T、私ははっきりと自分の利益のためにスパムにあまりにも多くのコンソールウィンドウを使用し得ている...
tanantish

1
するときに-SIGINFOが表示されない理由kill -l
フェリペアルバレス

2

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
}

ソース


17
少しのコンテキストと説明かもしれない?
キサキ14年

1

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

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

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

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

そのような値を事前に知ることができます(ユースケースのため)か、find + wcなどのコマンドを使用して検出できます

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

それでは、このコマンドをサブコマンドに入れてみませんか?=)
カービー

tar cfvz ~/mytarfile.tgz . | pv -s $(find . | wc -l) -l > /dev/null。それはあなたのために働きますか?
カービー

1

tqdmに基づく方法:

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

1

のMacOS、最初に使用可能なすべてのコマンドを持っていることを確認し、不足しているもの(例えばをインストールしpv使用して)醸造

tar 圧縮せずにしたい場合は、次のようにします:

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

圧縮する場合は、次のようにします。

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

注:進行状況バーが表示されるまでに時間がかかる場合があります。最初に小さいフォルダーを試して機能することを確認してから、folder-with-big-filesに移動します。


0

Debian / buster AMD64のプロメテウス(メトリックデータ)バックアップのいくつかの番号を以下に示します。

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

十分な空きディスク容量がないため、このジョブをキャンセルしました。

を使用して進行状況を監視するzstdためのコンプレッサーとしての実験:tarpv

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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.