6

圧縮 tar ( tar.gz )に追加したいファイルとディレクトリの配列があります。もともと、配列をループして各項目を tar に追加することを計画していました。

tar czf my_app.tar.gz

for app_item in "${app_items[@]}"
do
    tar rzf my_app.tar.gz $app_item
done

スクリプトを実行すると、圧縮された tar にファイルを追加できないことがわかりました。配列内の場所のリストから tar を作成する他の方法があるかどうか疑問に思っていました。

どんな助けでも大歓迎です!

4

2 に答える 2

8

この問題は、圧縮されたアーカイブでのみ発生します。最初に圧縮されていないアーカイブを作成して使用し、後でループが実行されたときに圧縮することを提案します。

tar cf my_app.tar --files-from /dev/null
for app_item in "${app_items[@]}"
do
    tar rf my_app.tar "$app_item"
done
gzip my_app.tar

@Matthias がコメントで指摘したように、空のアーカイブ (最初の行で必要なもの) の作成は通常、によって拒否されtarます。これを強制するには、オペレーティング システムごとに異なるトリックが必要です。

  • BSD :tar cf empty.tar --from-file /dev/null
  • GNU (リナックス) :tar cvf empty.tar --files-from /dev/null
  • ソラリス:tar cvf empty.tar -I /dev/null

これについての詳細は、彼がリンクしたページを説明しています。

スペースを含むファイル名でもうまく機能するように見える完全に異なるアプローチ(ただし、改行を含むファイル名では機能しないため、それほど一般的ではありません):

tar cfz my_app.tgz --files-from <(printf "%s\n" "${app_items[@]}")

そして、これを行うさらに別の方法(ファイル名の改行やその他のものでも機能します):

eval tar cfz my_app.tgz $(printf "%q " "${app_items[@]}")

ただし、いつものように、eval何を渡すかを知っておく必要があり、これが信頼できないソースからのものではないことを知っておく必要があります。そうしないと、セキュリティ上の問題が発生する可能性があるため、一般的には避けることをお勧めします。

于 2013-05-27T08:57:15.053 に答える
3

配列内の名前でファイルを作成し、-Ttar (BSD または GNU) のオプションを使用してそのファイルを読み取ります。これは、任意の数のファイルで機能し、名前にスペースが含まれるファイルで機能し、必要なディスク容量を最小限に抑えるためにアーカイブ中に圧縮します。例えば:

for (( i = 0;  i < ${#app_items[@]}; i++))
do
  echo ${app_items[$i]} >> items$$
done
tar cfz my_app.tar.gz -T items$$
rm items$$
于 2013-05-27T18:18:47.730 に答える