zip 格式的外部文件屬性
這是一個有點異國情調的問題,但網上似乎沒有太多關於此的資訊。我剛剛添加了一個關於 zip 格式的外部文件屬性的問題的答案。正如您從我的回答中看到的那樣,我得出的結論是,只有第二個字節(4 個字節)實際上用於 Unix。顯然這在解壓縮時包含足夠的資訊來推斷對像是文件還是目錄,並且還有空間用於其他權限和屬性資訊。我的問題是,這如何映射到通常的 Unix 權限?通常的 Unix 權限(例如下面)是否
ls
恰好適合一個字節,如果是這樣,有人可以描述佈局或提供參考嗎?$ ls -la total 36 drwxr-xr-x 3 faheem faheem 4096 Jun 10 01:11 . drwxrwxrwt 136 root root 28672 Jun 10 01:07 .. -rw-r--r-- 1 faheem faheem 0 Jun 10 01:07 a drwxr-xr-x 2 faheem faheem 4096 Jun 10 01:07 b lrwxrwxrwx 1 faheem faheem 1 Jun 10 01:11 c -> b
讓我通過提出一個具體問題來更具體地說明這一點。根據我上面回答中引用的Trac 更新檔,您可以使用下面的 Python 片段創建一個 zip 文件。
該
040755 << 16L
值對應於創建一個具有權限的空目錄drwxr-xr-x
。(我測試過)。我承認0755
對應於rwxr-xr-x
模式,但是04
, 以及整個值如何對應於一個字節呢?我也認識到<< 16L
對應於 16 位的按位左移,這將使其最終成為從高字節開始的第二個。def makezip1(): import zipfile z = zipfile.ZipFile("foo.zip", mode = 'w') zfi = zipfile.ZipInfo("foo/empty/") zfi.external_attr = 040755 << 16L # permissions drwxr-xr-x z.writestr(zfi, "") print z.namelist() z.close()
編輯:重讀這篇文章時,我認為我認為 Unix 權限僅對應一個字節的結論可能是不正確的,但我會讓上述內容代表目前,因為我不確定正確的答案是什麼。
EDIT2:我確實對僅對應於 1 個字節的 Unix 值不正確。正如@Random832 解釋的那樣,它同時使用了前兩個字節。根據@Random832 的回答,我們可以從他在下面給出的表格中構造所需的
040755
值。即:__S_IFDIR + S_IRUSR + S_IWUSR + S_IXUSR + S_IRGRP + S_IXGRP + S_IROTH + S_IXOTH 0040000 + 0400 + 0200 + 0100 + 0040 + 0010 + 0004 + 0001 = 40755
這裡的加法是以8 為基數的。
0040000
是 的傳統值S_IFDIR
,代表目錄的文件類型標誌。該類型使用16 位st_mode
值的前 4 位,0100000
是正常文件的值。外部文件屬性的高 16 位似乎用於特定於作業系統的權限。Unix 值與傳統的 Unix 實現相同。其他作業系統使用其他值。有關各種不同作業系統中使用的格式的資訊可以在 Info-ZIP 原始碼(下載或例如在 debian 中
apt-get source [zip or unzip]
)中找到 - 相關文件位於zipinfo.c
中unzip
,平台特定文件位於zip
.這些通常以八進制(以 8 為基數)定義;這在 C 和python中通過在數字前面加上 . 來表示
0
。這些值都可以在4.4BSD 版本的連結中
<sys/stat.h>
找到。這些不在 POSIX 標準中(而是定義了測試宏);但起源於 AT&T Unix 和 BSD。(在 GNU libc / Linux 中,值本身被定義為etc in ,儘管核心標頭檔可能更容易閱讀 - 這些值幾乎在任何地方都相同。)__S_IFDIR
bits/stat.h
#define S_IFIFO 0010000 /* named pipe (fifo) */ #define S_IFCHR 0020000 /* character special */ #define S_IFDIR 0040000 /* directory */ #define S_IFBLK 0060000 /* block special */ #define S_IFREG 0100000 /* regular */ #define S_IFLNK 0120000 /* symbolic link */ #define S_IFSOCK 0140000 /* socket */
當然,其他 12 位用於權限和 setuid/setgid/sticky 位,與 chmod 相同:
#define S_ISUID 0004000 /* set user id on execution */ #define S_ISGID 0002000 /* set group id on execution */ #define S_ISTXT 0001000 /* sticky bit */ #define S_IRWXU 0000700 /* RWX mask for owner */ #define S_IRUSR 0000400 /* R for owner */ #define S_IWUSR 0000200 /* W for owner */ #define S_IXUSR 0000100 /* X for owner */ #define S_IRWXG 0000070 /* RWX mask for group */ #define S_IRGRP 0000040 /* R for group */ #define S_IWGRP 0000020 /* W for group */ #define S_IXGRP 0000010 /* X for group */ #define S_IRWXO 0000007 /* RWX mask for other */ #define S_IROTH 0000004 /* R for other */ #define S_IWOTH 0000002 /* W for other */ #define S_IXOTH 0000001 /* X for other */ #define S_ISVTX 0001000 /* save swapped text even after use */
作為歷史記錄,使用
0100000
正常文件而不是 0 的原因是,在早期的 unix 版本中,0 用於“小”文件(這些文件不使用文件系統中的間接塊)並且模式標誌的高位是為將使用間接塊的“大”文件設置。在文件系統更改後,其他兩種使用此位的類型在後來的 unix 派生作業系統中添加。所以,總結一下,Unix 擴展屬性欄位的整體佈局是
TTTTsstrwxrwxrwx0000000000ADVSHR ^^^^____________________________ file type as explained above ^^^_________________________ setuid, setgid, sticky ^^^^^^^^^________________ permissions ^^^^^^^^________ This is the "lower-middle byte" your post mentions ^^^^^^^^ DOS attribute bits