圧縮したい大きなファイルをいくつか持っています。これは例えば
tar cvfj big-files.tar.bz2 folder-with-big-files
問題は、進捗状況が見えないので、どのくらいかかるのかなどの手がかりがないことです。v
を使えば、少なくとも各ファイルがいつ完了したかはわかるのですが、ファイルが少なくて大きい場合には、これはあまり参考になりません
もっと詳細な進捗状況を表示する方法はありますか?パーセンテージやプログレスバー、推定残り時間などのようなものです。一つのファイルごと、またはすべてのファイル、または両方のファイルについて
146 Svish 2010-07-28
私はこういうオネエの方が好きです
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
126 checksum 2013-10-25
pvで実現できます。進捗状況を正しく報告するためには、pv
はどのくらいのバイト数を投げているかを知る必要があります。そのため、まずはサイズ(kバイト単位)を計算する必要があります。また、プログレスバーを完全に落として、pv
にどれだけのバイト数を見たかを教えてもらうこともできます
% SIZE=`du -sk folder-with-big-files | cut -f 1`
And then:
% tar cvf - folder-with-big-files | pv -p -s ${SIZE}k | \
bzip2 -c > big-files.tar.bz2
79 akira 2010-07-28
より良いプログレスバー
apt-get install pv dialog
(pv -n file.tgz | tar xzf - -C target_directory ) \
2>&1 | dialog --gauge "Extracting file..." 6 50
28 Mr. Black 2012-08-28
tar 情報ページの --checkpoint
と --checkpoint-action
オプションを確認してください (私のディストリビューションでは、これらのオプションの説明は man ページ → RTFI にはありません)
https://www.gnu.org/software/tar/manual/html_section/tar_26.html を参照してください
これらを使えば(そして、独自のチェックポイントコマンドを書く機能もあるかもしれません)、パーセンテージを計算することができます
21 helper 2011-08-04
ヘルパーの答えに触発されて
もう一つの方法は、ネイティブのtar
オプションを使うことです
FROMSIZE=`du -sk --apparent-size ${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: [>>>>>>>>>>>>>>>>>>>>>>>
完全な例 こちら
13 campisano 2017-07-16
タールのみの使用
tar
には、--totals=$SIGNO
を使った信号のステータス情報を表示するオプションがあります(v1.12以降)
tar --totals=USR1 -czf output.tar input.file
Total bytes written: 6005319680 (5.6GiB, 23MiB/s)
Total bytes written: [...]
の情報は USR1 信号ごとに表示されます
pkill -SIGUSR1 tar
Source:
11 Murmel 2018-06-15
MacOS についてのコメントにちょうど気がついたので、@akira (と pv) の解決策の方がずっといいと思うのですが、私の MacOS の箱に tar を入れて SIGINFO シグナルを送信して、直感を追いかけてみました。おかしなことに、それはうまくいきました 🙂 BSD ライクなシステムを使っている場合はうまくいくはずですが、Linux の場合は SIGUSR1 を送る必要があるかもしれませんし、tar
が同じようにはいかないかもしれません
欠点は、取得しているデータストリームがどのくらいの大きさなのかわからないと思うので、現在のファイルがどのくらいの距離にあるのかを示す出力(標準出力)しか提供してくれないということです
そうですね、別の方法としては、tarを起動して定期的にSIGINFOsを送るという方法があります。どうやってやるの?
アドホックでマニュアル的なアプローチ
もしその場しのぎでステータスをチェックしたいのであれば、関連するウィンドウで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 を調べて、それをスクリプトに放り込んで、繰り返しシグナルを送信するという方法もあります。例えば、以下のようなスクリプトレットがあるとします (そして 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 2012-04-21
ノア・スパーリエの回答に触発されて
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
}
3 Steven Penny 2012-04-18
tqdm に基づく方法
tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
2 J_Zar 2018-04-27
全部の合計サイズではなく、ファイル番号を知っていた場合
別の方法としては、-l オプションを使用して、データの内容の代わりにファイル名を unix パイプで送るという方法があります (正確さは劣りますが適切です)
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 2017-09-15
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 Bugs Bunny 2019-09-02
どれだけ残っているかはわかりませんが、コマンド--checkpoint=1000
に非常に簡単な足し算で進んでいることがわかります
# tar xf file.tar --checkpoint=1000
tar: Read checkpoint 1000
tar: Read checkpoint 2000
tar: Read checkpoint 3000
tar: Read checkpoint 4000
tar: Read checkpoint 5000
tar: Read checkpoint 6000
...
https://www.gnu.org/software/tar/manual/html_section/tar_25.html の詳細はこちら
1 Rub 2020-03-17
でダイアログとpvコマンドをインストールします
sudo apt-get install dialog pv
で、こんな感じでtarを実行します
(tar cf - /folder-with-big-files | pv -n -s $(du -sb /folder-with-big-files | awk '{print $1}') | gzip -9 > big-files.tar) 2>&1 | dialog --gauge 'Your backup is in progress...' 7 70
1 Savman 2020-04-27
Debian/バスターAMD64上のプロメテウス (メトリクスデータ) のバックアップの数は以下の通りです
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 dileks 2019-09-13
私が普段使っているものでは、動作している場合と、(時には)完成間近の場合のみ、正確なパーセントレベルの進行状況を知る必要はありません
私はこの必要性を最小限に抑えるために、Bash で処理されたファイルの数を独自の行で表示することで解決しています
let n=0; tar zcvf files.tgz directory | while read LINE; do printf "\r%d" $((n++)) ; done ; echo
よく使うので、.bashrcで関数のエイリアスを定義しました
function pvl { declare -i n=0; while read L ; do printf "\r%d" $((++n)) ; done ; echo ; }
Then simply:
tar zcvf files.tgz directory | pvl
必要であれば、find directory | wc -l
でファイル数を事前に計算することができます(あるいは、私の焦りを押しつぶすために、[find directory | pvl
]で示されているのと同じ関数を使った方がいいかもしれません!)
他の例としては、仮想Webサイトの権利設定(その後、ファイル名がファイルシステムのキャッシュにあるのでchown -R
が速い)などがあります
find /site -print -type d -exec chmod 2750 "{}" \; -o -type f -exec chmod 640 "{}" | pvl
確かにこの横方向の処理がメインの動作を遅くしてしまうのは事実ですが、戻り文字と数桁の数字を印刷するのはあまり高くはないと思います(それに、次の等号が出てくるのを待ったり、パーセントの桁が変わるのを待ったりするのは、桁が変わるという主観的なスピードに比べて遅く感じてしまいます!)
0 Fjor 2020-02-25
7zを使っても大丈夫なら
7z a example.tar example/
これにより、走査駆動ステージが表示されます
Scanning the drive:
2608M 139834 Scan example/file.txt
など、見ておいて損はない情報がいくつかあります
Scanning the drive:
157318 folders, 601997 files, 13683142277 bytes (13 GiB)
Creating archive: example.tar
Items to compress: 759315
3% 29587 + example/file.txt
0 qwr 2020-05-28