Проблема, связанная с расширением Zip4, перенаправлением стандартного входного содержимого в zip-архив, использованием zip и использованием zipnotes для изменения имени zip-файла - PullRequest
0 голосов
/ 11 октября 2019

У меня раздражающая проблема с программами zip и zipnote (обе в версии 3.0) на моей стабильной платформе Debian.

Я хочу создать zip-архив, хранящий (не сжимая) данные из стандартныхвход без дополнительных атрибутов / полей и присвоения имени результирующему файлу внутри zip-файла.

Моя первая попытка была

printf "foodata"          | zip -X0 bar.zip - 
printf "@ -\n@=foofile\n" | zipnote -w bar.zip

, где zip создать архив bar.zipс сохраненным файлом "-", содержащим "foodata", и zipnote переименуйте файл с "-" на "foofile".

Первая проблема (решена): zip, как мы видим изzipdetails

001E Filename              '-'
001F Extra ID #0001        0001 'ZIP64'
0021   Length              0010
0023   Uncompressed Size   0000000000000007
002B   Compressed Size     0000000000000007

получая данные из стандартного ввода, не знает размер результирующего файла, поэтому создайте PKZIP 4.5-совместимый архив zip (который может превышать 4 ГБ), используя расширение Zip64и добавление в файл дополнительного атрибута Zip64.

А опция -X удаляет атрибуты extrafile , но не удаляет дополнительное поле Zip64.

Эта проблема легко решается добавлением опции -fz-, как указано в zip man page

// .................................VVVV
printf "foodata"          | zip -X0 -fz- bar.zip - 

Теперь bar.zip - это файл, совместимый с PKZIP 2, и нет дополнительного поля Zip64.

Вторая проблема (не решена): zipnote измените имя файла и добавьте в файл поле Zip64.

Я не знаю почему.

По словам zip manpage

zip удаляет расширения Zip64, если они не нужны при копировании архивных записей (см. параметр -U (--copy)).

Итак, японимаю, что

zip bar.zip --out bar-corrected.zip

должен создать новый bar-corrected.zip архив, в котором расширение foofile is Zip64 free (the foofile is very short so the Zip64`, я полагаю, не требуется).

К сожалению, это не работает: я получаю предупреждение

 copying: foofile
    zip warning: Local Version Needed To Extract does not match CD: foofile

, и полученный файл поддерживает расширение Zip64.

И кажется, что не работает объяснение имени файла илидобавив опцию -fz-: я перепробовал много комбинаций, но (возможно, это моя вина) безуспешно.

Вопросы:

(1) можно ли избежать (икак) что zipnote, меняя имя файла, добавляет в него поля Zip64?

(2) в противном случае, как я могу использовать zip--copy? С -fz-?), Чтобы создать новое расширение zip archive Zip64 free?

Ответы [ 2 ]

1 голос
/ 11 октября 2019

[Редактировать: Обновлено для использования Store вместо Deflate]

Не уверен, как достичь того, что вы хотите с zip и zipnote, но здесь есть альтернатива.

echo abc | perl -MIO::Compress::Zip=zip -e ' zip "-" => "out.zip", Method => 0, Name => "member.txt" '

$ unzip -lv out.zip 
Archive:  out.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       4  Stored        4   0% 2019-10-10 21:54 4788814e  member.txt
--------          -------  ---                            -------
       4                4   0%                            1 file

Zip64 или дополнительные атрибуты отсутствуют в zip-файле.

$ zipdetails out.zip 

0000 LOCAL HEADER #1       04034B50
0004 Extract Zip Spec      14 '2.0'
0005 Extract OS            00 'MS-DOS'
0006 General Purpose Flag  0008
     [Bit  3]              1 'Streamed'
0008 Compression Method    0000 'Stored'
000A Last Mod Time         4F4AAECA 'Thu Oct 10 21:54:20 2019'
000E CRC                   00000000
0012 Compressed Length     00000000
0016 Uncompressed Length   00000000
001A Filename Length       000A
001C Extra Length          0000
001E Filename              'member.txt'
0028 PAYLOAD               abc.

002C STREAMING DATA HEADER 08074B50
0030 CRC                   4788814E
0034 Compressed Length     00000004
0038 Uncompressed Length   00000004

003C CENTRAL HEADER #1     02014B50
0040 Created Zip Spec      14 '2.0'
0041 Created OS            03 'Unix'
0042 Extract Zip Spec      14 '2.0'
0043 Extract OS            00 'MS-DOS'
0044 General Purpose Flag  0008
     [Bit  3]              1 'Streamed'
0046 Compression Method    0000 'Stored'
0048 Last Mod Time         4F4AAECA 'Thu Oct 10 21:54:20 2019'
004C CRC                   4788814E
0050 Compressed Length     00000004
0054 Uncompressed Length   00000004
0058 Filename Length       000A
005A Extra Length          0000
005C Comment Length        0000
005E Disk Start            0000
0060 Int File Attributes   0000
     [Bit 0]               0 'Binary Data'
0062 Ext File Attributes   81A40000
0066 Local Header Offset   00000000
006A Filename              'member.txt'

0074 END CENTRAL HEADER    06054B50
0078 Number of this disk   0000
007A Central Dir Disk no   0000
007C Entries in this disk  0001
007E Total Entries         0001
0080 Size of Central Dir   00000038
0084 Offset to Central Dir 0000003C
0088 Comment Length        0000
Done
0 голосов
/ 15 октября 2019

Создан простой скрипт, который оборачивает предыдущий ответ. См. streamzip

Использование

 printf "foodata" | streamzip -method=store -member-name=foofile -zipfile=/tmp/bar.zip

Это то, что, по мнению unzip, находится в zip-файле

unzip -lv /tmp/bar.zip
Archive:  /tmp/bar.zip
 Length   Method    Size  Cmpr    Date    Time   CRC-32   Name
--------  ------  ------- ---- ---------- ----- --------  ----
       7  Stored        7   0% 2019-10-15 20:25 1b7dd7cd  foofile
--------          -------  ---                            -------
       7                7   0%                            1 file
...