bsdtar
我遇到过,包中的命令libarchive
(至少在 Arch Linux 下).zip
在读取时会丢弃 -archives中文件的可执行位stdin
,但在直接处理文件时则不会。
在.tar
-archives 上,它在从标准输入读取时也保留可执行位。
测试用例:
创建档案:
创建文件:
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
zip
(使用和tar
而不是创建档案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.out
为 755 和a.txt
644。
阅读自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
Zip 档案包含两种不同的方式来描述内容:
- 每个条目的标头
- zip 文件末尾的中心目录。
如果可以在输入上查找,libarchive(以及扩展的 bsdtar)将使用中央目录,否则它将回退到仅流逻辑。正如您在测试用例中发现的那样,这些条目不一定一致。我们对此无能为力或不想做太多事情。请注意,您可以用普通的猫替换 wget,它仍然会显示相同的行为。
简而言之,这是 zip 文件流的固有问题,并且无法修复。
和这条评论讲述如何使用以下命令创建一致的 ZIP 文件bsdtar
:
为了使bsdtar
创建信息一致,--options zip:experimental
需要在bsdtar
zip文件创建命令中添加:
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
有打印错误信息并以非零状态退出。它可能应该对 zip 文件做同样的事情;恕我直言,默默地搞乱权限是不可接受的。
$ 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