圧縮したい大きなファイルがいくつかあります。私はこれを行うことができます例えば
tar cvfj big-files.tar.bz2 folder-with-big-files
問題は私が進歩を見ることができないということである、それで私はそれがどれくらいかかるか、またはそのような何かがどのくらいかかるかについての手がかりがない。 v
を使うと、少なくとも各ファイルがいつ完成するかを見ることができますが、ファイルが少なくて大きくても、これは最も役に立ちません。
より詳細な進捗状況を示すためにtarを取得する方法はありますか?完了率、進行状況バー、推定残り時間などのようなものです。各単一ファイル、またはそれらすべて、あるいはその両方に対して。
私はこのような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
これを達成するために 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
より良いプログレスバー..
apt-get install pv dialog
(pv -n file.tgz | tar xzf - -C target_directory ) \
2>&1 | dialog --gauge "Extracting file..." 6 50
Tar infoページの--checkpoint
および--checkpoint-action
オプションを調べてください(私のディストリビューションに関しては、これらのオプションの説明はmanページ→RTFIには含まれていません)。
https://www.gnu.org/software/tar/manual/html_section/tar_26.html を参照してください。
これら(そしてあなた自身のチェックポイントコマンドを書く機能)を使えば、パーセンテージを計算できます。
ヘルパーの答え からヒントを得た
別の方法はネイティブの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: [>>>>>>>>>>>>>>>>>>>>>>>
完全な例 はこちら
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
ソース:
ちょうど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)
...
私が認めるものはちょっとかわいいです。
大事なことを言い忘れましたが - 私のスクリプティングはちょっとさびたので、誰かが入ってコードをクリーンアップ/修正/改善したいのなら、あなたの人生のために行ってください:)
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
}
tqdm に基づく方法:
tar -v -xf tarfile.tar -C TARGET_DIR | tqdm --total $(tar -tvf tarfile.tar | wc -l) > /dev/null
すべてのファイルの合計サイズではなくファイル番号を知っている場合:
別の方法(正確ではありませんが適しています)は、-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