約1GBのファイルをtarアーカイブにパッケージ化するBashスクリプト

約1GBのファイルをtarアーカイブにパッケージ化するBashスクリプト

それぞれのサイズが約3〜10 GBの数千のファイルを含む複数のフォルダがあります。今、これらのファイルをフォルダにパッケージ化したいと思います。各tarファイルのサイズは約1 GBでなければなりません。後でPythonを使用してこれらのtarファイルを処理したいと思います。

#!/bin/bash

dirlist=$(find $1 -mindepth 1 -maxdepth 1 -type d)
stored_date=$(date +%Y-%m-%d --date="-1 day")
#stored_date='2019-10-23'

for dir in $dirlist
do
(
    cd $dir
    tar_file=${PWD##*/}  
    tar_file="${tar_file}_${stored_date}.tar"

    echo "${tar_file}"

    tar -c $stored_date*.html --tape-length=1000M  -f ${tar_file}  --remove-files
)
done

1GBのチャンクを生成するのはうまくいきますが、Pythonには "--tape-length"オプションを使用するときにあらゆる種類の問題があります。

tarfile.ReadError: 予期しないデータの終わり

(また、Pythonを使用してtarアーカイブの端から分割されたファイルを処理したい)

Linuxにこの問題に対する解決策はありますか? tarの代わりにstarを見つけましたが、まだ試していません。可能であれば、標準のtarを使用することをお勧めします。

答え1

tarファイルに追加する前に、各ファイルのサイズを追跡するために各ディレクトリループ内に2番目のループを入れ子にするのはどうですか?私が意味するものの概略的な擬似コードは次のとおりです。

max_size=$((1024*1024*1024))
total_size=0
for dir in $dirlist ; do
  for foo in $dir/*; do
    this_size="$(stat -c"%s" $foo)"
    if [ $(($total_size + $this_size)) -le $max_size ] ; then
      tar --append ... $foo
      total_size="$(($total_size + $this_size))"
    else
      # start new tar file here
      tar -c ... $foo
      total_size="$this_size"
    fi
  done
done

答え2

私が知っている限り、Pythonはtar形式を理解していないので、tarアーカイブ標準と100%互換性のないtarアーカイブモジュールを使用する方が良いかもしれません。これは考慮すべき重要な事項です。公式の機能セットのサブセットのみをサポートする未完成のtar実装がたくさんあります。

モードに入らずにこのオプションを使用することをお勧めしますstar。これにより、ファイルが途中で分割されるのを防ぎますが、指定されたテープサイズより大きいファイルは保持できません。-tsizestarmulti volumestar

デフォルトのシェル "sh" が "$((expr))" サポートで POSIX 仕様である場合、そうでない場合は、 "sh -c" を "ksh -c" またはそれと同じものに置き換えます。

...どうですか?

cd /tmp
star -C path/to/archivedir -c tsize=1G \
new-volume-script='cd /tmp;sh -c "mv vol-last.tar vol\$((\$1-1)).tar" script' \
f=vol-last.tar .

これにより、生成されたTARアーカイブが/ tmpに残ります。 vol-last.tarの名前を最終予想ボリューム番号に手動で変更する必要があります。最後のアーカイブを含め、すべてのアーカイブの最後まで新しいボリュームスクリプトを実行するようにスターを拡張することを検討できます。

関連情報