2010-07-28 11:51:37 +0000 2010-07-28 11:51:37 +0000
133
133
Advertisement

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

Advertisement

私は圧縮したい大きなファイルをいくつか持っています。

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

のようにして圧縮することができますが、問題は、進捗状況を見ることができないので、どのくらいの時間がかかるのかなどの手掛かりがないことです。v を使うことで、少なくとも各ファイルが完成したときにはわかるのですが、ファイルが少なくて大きい場合にはあまり参考になりません。

もっと詳細な進捗状況を表示する方法はありますか?完了率やプログレスバー、残り時間の目安など。一つのファイルごと、または全てのファイル、またはその両方。

Advertisement
Advertisement

回答 (13)

109
109
109
2013-10-25 08:15:15 +0000

こんな感じのオネリがいいですね。

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
77
77
77
2010-07-28 12:01:07 +0000

これを実現するには、 pv を使用することができます。進捗状況を正しく報告するためには、pvはどれだけのバイト数を投げているかを知る必要があります。そのため、まず最初のステップはサイズを計算することです(単位はkバイト)。また、プログレスバーを完全に削除して、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
23
Advertisement
23
23
2012-08-28 08:26:14 +0000
Advertisement

より良いプログレスバー…

apt-get install pv dialog

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

17
17
17
2011-08-04 20:53:06 +0000

tar 情報ページの --checkpoint--checkpoint-action のオプションをチェックしてみてください(私のディストリビューションでは、これらのオプションの説明は man ページには含まれていません→RTFI)。

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

これらを使えば、パーセンテージを計算することができます…

11
Advertisement
11
11
2017-07-16 00:22:25 +0000
Advertisement

ヘルパーの答え ](https://superuser.com/a/319207/726186)

もう一つの方法は、ネイティブの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
8
8
2018-06-15 05:03:41 +0000

**

tar は、--totals=$SIGNO を使用している信号のステータス情報を表示するオプションがあります (v1.12 以降)。

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

Total bytes written: [...] は、0x6& を使用した信号のステータス情報を表示するオプション(v1.12 以降)があります。

pkill -SIGUSR1 tar

ソース:

3
Advertisement
3
3
2012-04-21 20:44:39 +0000
Advertisement

MacOS についてのコメントに気付いたばかりで、@akira (と pv) の解決策の方がはるかに良いと思うのですが、私の MacOS の箱に tar を入れて SIGINFO シグナルを送信して、直感を追いかけてみました。おかしなことに、それはうまくいきました :) BSD ライクなシステムを使っているなら、これはうまくいくはずですが、Linux の場合は SIGUSR1 を送る必要があるかもしれませんし、tar は同じようにはいかないかもしれません。

欠点は、取得しているデータストリームがどのくらいの大きさなのかを知らないと推測されるので、現在のファイルがどのくらいの距離にあるのかを示す出力(標準出力)しか提供してくれないことです。

ですから、別の方法としては、tarを起動して、定期的にSIGINFOsを送信して、どのくらいの距離にあるのかを知りたいときにいつでもそれを送信するという方法があります。どうすればいいのでしょうか?

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

アドホックにステータスをチェックしたい場合は、関連するウィンドウで(Brian Swift が言及したように)control-T を押すと SIGINFO シグナルが送信されます。これは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 を計算し、スクリプトに投入して繰り返しシグナルを送信するという方法もあります。例えば、以下のようなスクリプトレットがあるとします (そして、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)
...

これは、私が認めるように、ちょっときれいなものです。

0x1&

これは認めるよ。)

2
2
2
2012-04-18 01:00:19 +0000

ノア・スパーリエの答え ](https://stackoverflow.com/a/3554912)

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
}

ソース に触発されて

1
Advertisement
1
1
2017-09-15 12:38:27 +0000
Advertisement

**

代替手段(正確性は低いですが適しています)としては、-l オプションを使用して、データの内容ではなくファイル名を unix パイプで送信する方法があります。

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

このような値を事前に知ることもできますし、(あなたの使用例により) find+wc のようなコマンドを使用して発見することもできます。

1
1
1
2019-09-02 20:05:09 +0000

macOS**では、まずすべてのコマンドが利用可能であることを確認し、不足しているコマンド(例:pv)を brew でインストールしてください。

圧縮なし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

注意: プログレスバーが表示されるまでに時間がかかる場合があります。最初に小さいフォルダで試して動作することを確認してから、大きなファイルのあるフォルダに移動してください。

1
1
1
2018-04-27 06:44:10 +0000

tqdm](https://github.com/tqdm/tqdm#usage)に基づくメソッド。

tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
0
0
0
2019-09-13 15:39:11 +0000

以下は Debian/バスター AMD64 上の prometheus (メトリクスデータ) バックアップの数値です:

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

利用可能なディスクスペースが不足していたため、このジョブをキャンセルしました。

zstd のコンプレッサーとして tar を使用し、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
0
0
0
2020-02-25 22:54:21 +0000

私の日常的な使用では、操作の正確なパーセントレベルの進行状況を知る必要はありませんが、動作しているかどうかと、(時には)完了に近づいているかどうかだけを知る必要があります。

let n=0; tar zcvf files.tgz directory | while read LINE; do printf "\r%d" $((n++)) ; done ; echo

私はこの必要性を最小限に抑えるために、処理されたファイルの数を独自の行で表示することで解決しています; Bash:

function pvl { declare -i n=0; while read L ; do printf "\r%d" $((++n)) ; done ; echo ; }

私はこれをよく使うので、. bashrc:

tar zcvf files.tgz directory | pvl

あとは単純に:

find /site -print -type d -exec chmod 2750 "{}" \; -o -type f -exec chmod 640 "{}" | pvl

必要に応じて find directory | wc -l を使ってファイル数を事前に計算することができます (あるいは、[find directory | pvl] で示されているのと同じ関数を使って私のせっかちさを潰した方が良いでしょう!)。

もう一つの例では、仮想ウェブサイトの権利を設定しています(その後、ファイル名がファイルシステムのキャッシュにあるので、chown -Rを使うのが速いです)。

0x1&

0x1&

この横の処理は確かにメインの処理を遅くしてしまうかもしれませんが、戻り文字と数桁の数字を印刷するのはあまりコストがかからないと思います(それに加えて、次の等号が出るのを待ったり、パーセントの桁が変わるのを待ったりするのは、数字が変わるという主観的なスピードに比べて遅いと感じます!)。

Advertisement

関連する質問

10
37
7
14
6
Advertisement