Цель состоит в том, чтобы прочитать zip-файл со стандартного ввода и распаковать его в стандартный вывод.
Funzip работает и является решением, которое я ищу, zip содержит один файл, к сожалению, funzip не работает, когда размер сжатого файла составляет около 1 ГБ или больше:
funzip error: invalid compressed data--length error
Обновление: я обнаружил, что указанная выше ошибка может не указывать на действительную ошибку. Сравнивая два несжатых файла, один из которых разархивирован традиционно, а другой через конвейер с использованием funzip (с указанной выше ошибкой, записанной в stderr), файлы идентичны. Я хотел бы оставить это открытым, чтобы это можно было подтвердить или сообщить.
Связанное решение с использованием python: Распаковка файлов, которые летают по трубе
Однако этот вывод направляется в файл.
Просто используйте zcat
. Например:
cat file.zip | zcat
Обратите внимание, что в приведенном выше примере первая часть (cat file.zip
) является избыточным в том смысле, что вы можете просто выполнить zcat file.zip
и получить те же результаты. Я включил это только для того, чтобы показать, что zcat
способен читать из stdin
Репост мой ответ:
BusyBox's unzip
может взять стандартный ввод и извлечь все файлы в стандартный вывод. Например, когда вы используете wget
как стандартный ввод,
wget -qO- http://downloads.wordpress.org/plugin/akismet.2.5.3.zip | busybox unzip -p -
-p
для извлечения файлов в канал. Тире после означает использование стандартного ввода в качестве ввода.
Вы также можете (как и предыдущий ответ)
cat file.zip | busybox unzip -p -
Но это просто лишнее unzip -p file.zip
.
Если ваш дистрибутив по умолчанию использует BusyBox (например, Alpine), просто запустите unzip -p -
.
Распаковка (с перенаправлением на file
):
cat file.gz | gunzip -c - > file
Сжатие (с перенаправлением на file.gz
)):
cat file | gzip -c - > file.gz
Что касается stdout: unzip поддерживает это из коробки с параметрами -c и -p. относительно stdin: Эрик указал, что у формата zip есть каталог в конце файла, поэтому единственный способ сделать его потоковым - скопировать ввод во временное хранилище. Это делает следующий простой скрипт:
#!/bin/bash
# usage: unzipOnTheFly [unzipArgs]
# unzipArgs: additional args to be passed to unzip
tmpFile=/tmp/unzipOnTheFly.$$.zip
cat >$tmpFile
unzip -p $tmpFile "$@"
rm $tmpFile
В приведенном выше случае решение было бы
<file.zip unzipOnTheFly
Если архив содержит более одного файла, а вам нужен только один, вы можете сказать
<file.zip unzipOnTheFly pathToOneFile