libarchiveのbsdtar解凍がZIPアーカイブを直接読み取るのではなく、stdinから読み込むときに許可ビットを削除するのはなぜですか?

libarchiveのbsdtar解凍がZIPアーカイブを直接読み取るのではなく、stdinから読み込むときに許可ビットを削除するのはなぜですか?

bsdtarlibarchiveパッケージ(少なくともArch Linuxでは)のコマンドがを.zip読み取るときに-archivesにあるファイルの実行可能ビットを削除しますstdinが、ファイルを直接処理するときは削除しないことを見たことがあります。

-archives では、.tar標準入力から読み取る際に実行可能なビットも保存します。

テストケース:

アーカイブの作成:

ファイルを生成します。

touch a.txt
chmod 644 a.txt
touch a.out
chmod 755 a.out

ファイル権限:

ls -ln a.out a.txt

プログラム

-rwxr-xr-x 1 1001 1001 0 Dec 12 11:01 a.out
-rw-r--r-- 1 1001 1001 0 Dec 12 11:01 a.txt

ファイルをアーカイブに圧縮します。

bsdtar --format=zip -cf a.zip a.out a.txt
bsdtar -cf a.tar a.out a.txt

ziptarCREATEアーカイブの代わりにANDを使用すると、bsdtar同じ結果が生成されます。)

アーカイブコンテンツを直接抽出/表示:

bsdtar -tvf a.zip

または

bsdtar -tvf - < a.zip

プログラム

-rwxr-xr-x  0 1001   1001        0 Dec 12 11:01 a.out
-rw-r--r--  0 1001   1001        0 Dec 12 11:01 a.txt

ここに表示される実行可能ビットですa.out。権限はa.out755とa.txt644です。

読むstdin

cat a.zip | bsdtar -tvf -

プログラム

-rw-rw-r--  0 1001   1001        0 Dec 12 11:01 a.out
-rw-rw-r--  0 1001   1001        0 Dec 12 11:01 a.txt

ここで実行可能なビットはa.out削除されます。また、両方のファイルはグループ書き込みが可能ですが、そのようにパッケージ化されません。a.outとの権限はa.txtすべて664です。

.tar-ファイル:

これに対して.tar-archive の場合、パイプから読み取る際にアーカイブの権限も尊重されますstdin

bsdtar --numeric-owner -tvf a.tar

そして

cat a.tar | bsdtar --numeric-owner -tvf -

みんな見える

-rwxr-xr-x  0 1001   1001        0 Dec 12 11:01 a.out
-rw-r--r--  0 1001   1001        0 Dec 12 11:01 a.txt

(ZIPアーカイブの内容を表示すると、デフォルトでは数値bsdtar所有者が表示されます。TARアーカイブの場合は所有者名が表示されます。)

問題は次のとおりです。

何がstdinそんなに特別ですかbsdtar?なぜファッションではなくパイプで読むときにのみ読むことができますかbsdtar -tvf - < a.zip.zip-archiveが特別で、-archiveではないのはなぜですか.tar

答え1

バグトラッカーからlibarchive正解は:

Zipアーカイブには、コンテンツを記述する2つの方法が含まれています。

  1. 各項目のヘッダー
  2. zipファイルの末尾にある中央ディレクトリ。

libarchive(および拡張bsdtar)は、入力から検索できる場合は中央ディレクトリを使用し、それ以外の場合はストリーム専用ロジックに置き換えられます。テストケースで見たように、これらの項目は必ずしも一貫しているわけではありません。これについて私たちができることやしたいことはあまりありません。 wgetを通常の猫に置き換えても、同じ動作が表示されます。

簡単に言えば、これはzipファイルストリームの本質的な問題であり、これを解決する方法はありません。

そしてこのコメント次のコマンドを使用して一貫したZIPファイルを作成する方法を説明しますbsdtar

bsdtar生成情報の一貫性を維持するには、zipファイル生成コマンドに以下を追加する必要が--options zip:experimentalあります。bsdtar

bsdtar --format=zip --options zip:experimental -cf a.zip a.out a.txt

それから

cat a.zip | bsdtar -tvf -

正しい権限を表示:

-rwxr-xr-x  0 1001   1001        0 Feb 17 21:18 a.out
-rw-r--r--  0 1001   1001        0 Feb 17 21:18 a.txt

答え2

[まだ回答ではありませんが、コメントに形式を指定できないため、このように投稿します。]

zip検索できないファイルから抽出するときに問題を引き起こす唯一の形式ではありません。以下はマルチセッションISOイメージの例ですが、少なくともbsdtar印刷されます。エラーメッセージゼロ以外の状態で終了します。 IMHOファイルに対しても同じことを行う必要があり、自動的に権限を操作することはできません。

$ echo a.out > a.out
$ genisoimage -quiet -R -o a.iso a.out
$ chmod 755 a.out
$ growisofs -M a.iso -R -quiet a.out
Executing 'genisoimage -C 16,176 -M /dev/fd/3 -R -quiet a.out | builtin_dd of=a.iso obs=32k seek=11'
Rock Ridge signatures found
builtin_dd: 176*2KB out @ average infx1352KBps
a.iso: copying volume descriptor(s)

$ cat a.iso | bsdtar xf -
bsdtar: Ignoring out-of-order file @19 (a.out) 51200 < 411648
bsdtar: Error exit delayed from previous errors.
$ ls -l a.out; hd a.out
-rwxr-xr-x 1 ahq ahq 6 Dec 11 19:15 a.out
00000000  00 00 00 00 00 00                                 |......|
00000006

$ bsdtar xf a.iso
$ ls -l a.out; hd a.out
-rwxr-xr-x 1 ahq ahq 6 Dec 11 19:15 a.out
00000000  61 2e 6f 75 74 0a                                 |a.out.|
00000006

関連情報