it-swarm-ru.tech

Как перенаправить вывод wget как вход для распаковки?

Я должен скачать файл с этой ссылка . Загружаемый файл представляет собой Zip-файл, который мне нужно будет распаковать в текущую папку.

Обычно я сначала загружаю его, затем запускаю команду unzip.

$ wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip
$ unzip temp.Zip

Но, таким образом, мне нужно выполнить две команды, дождаться завершения первой, чтобы выполнить следующую, также я должен знать имя файла temp.Zip чтобы передать его unzip.

Можно ли перенаправить вывод wget в unzip? Что-то вроде

$ unzip < `wget http://www.vim.org/scripts/download_script.php?src_id=11834`

Но это не сработало.

баш: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip: неоднозначное перенаправление

Кроме того, wget выполнялось дважды и загружало файл дважды.

142
Andrew-Dufresne

Вы должны загрузить свои файлы во временный файл, потому что (цитируя распакованную страницу руководства):

Архивы, считанные из стандартного ввода, пока не поддерживаются, за исключением funzip (и тогда может быть извлечен только первый элемент архива).

Просто соберите команды:

wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip; unzip temp.Zip; rm temp.Zip

Но для того, чтобы сделать его более гибким, вы, вероятно, должны поместить его в скрипт, чтобы сохранить некоторую типизацию и, чтобы избежать случайной перезаписи чего-либо, вы можете использовать команду mktemp для создания безопасного имени файла для вашего временного файла:

#!/bin/bash
TMPFILE=`mktemp`
PWD=`pwd`
wget "$1" -O $TMPFILE
unzip -d $PWD $TMPFILE
rm $TMPFILE
105
tante

Это перепост мой ответ на похожий вопрос:

Формат файла Zip включает в себя каталог (индекс) в конце архива. В этом каталоге указывается, где в архиве находится каждый файл, и, таким образом, обеспечивается быстрый произвольный доступ без чтения всего архива.

Это может создать проблему при попытке чтения Zip-архива через канал, поскольку доступ к индексу не осуществляется до самого конца, и поэтому отдельные элементы не могут быть правильно извлечены до тех пор, пока файл не будет полностью прочитан и больше не доступен , Таким образом, неудивительно, что большинство декомпрессоров Zip просто перестают работать, когда архив подается по каналу.

Каталог в конце архива - это не только место, где метаинформация файла хранится в архиве. Кроме того, отдельные записи также включают эту информацию в локальный заголовок файла для целей резервирования.

Хотя не каждый декомпрессор Zip будет использовать локальные заголовки файлов, когда индекс недоступен, внешние интерфейсы tar и cpio для libarchive (также известные как bsdtar и bsdcpio) могут и будут делать это при чтении через канал, что означает следующее:

wget -qO- http://example.org/file.Zip | bsdtar -xvf-
84
ruario

Если у вас установлен JDK, вы можете использовать jar:

wget -qO- http://example.org/file.Zip | jar xvf /dev/stdin
22
Rory Hunter

Я не думаю, что вы даже хотите докучать о выводе wget в распаковку.

Из википедии "Zip (формат файла)" статья:

Zip-файл определяется наличием центрального каталога, расположенного в конце файла.

wget должен полностью завершить загрузку, прежде чем unzip сможет выполнить какую-либо работу, поэтому они запускаются последовательно, а не переплетаются, как можно подумать.

15
Bruce Ediger

Правильный синтаксис будет:

$ unzip <(curl -sL https://www.winpcap.org/archive/1.0-docs.Zip)

но это не сработает из-за ошибки ( Info-Zip в Debian ):

lseek(3, 0, SEEK_SET)                   = -1 ESPIPE (Illegal seek)

Archive:  /dev/fd/63
  End-of-central-directory signature not found.  Either this file is not
  a zipfile, or it constitutes one disk of a multi-part archive.  In the
  latter case the central directory and zipfile comment will be found on
  the last disk(s) of this archive.
unzip:  cannot find zipfile directory in one of /dev/fd/63 or
        /dev/fd/63.Zip, and cannot find /dev/fd/63.Zip, period.

или на BSD/OS X:

Trying to read large file (> 2 GiB) without large file support

Это потому, что стандартные инструменты Zip в основном используют lseek function , чтобы установить смещение файла в конце для чтения его конца центрального запись каталога . Он расположен в конце структуры архива и требуется для чтения списка файлов (см .: Структура формата Zip-файла ). Поэтому файл не может быть FIFO, каналом, оконечным устройством или любой другой динамикой, поскольку входной объект не может быть позиционирован функцией lseek.

Итак, у вас есть следующие обходные пути:

  • используйте другой тип сжатия (например, tar.gz),
  • вы должны использовать две отдельные команды,
  • использовать альтернативные инструменты (как предлагается в других ответах),
  • создать псевдоним или функцию для использования нескольких команд.
11
kenorb

Репост мой ответ :

unzip BusyBox может взять стандартный ввод и извлечь все файлы.

wget -qO- http://downloads.wordpress.org/plugin/akismet.2.5.3.Zip | busybox unzip -

Черта после unzip должна использовать stdin в качестве входных данных.

Вы можете даже,

cat file.Zip | busybox unzip -

Но это просто излишне unzip file.Zip.

Если ваш дистрибутив по умолчанию использует BusyBox (например, Alpine), просто запустите unzip -.

11
Saftever

Если в Zip есть только один файл, вы можете использовать zcat или gunzip:

wget -qO- http://www.vim.org/scripts/download_script.php?src_id=11834 | gunzip

К вашему сведению: Вот определения gunzip и ​​zcat в моей системе:

$ grep ^exec $(which gunzip zcat)
/bin/gunzip:exec gzip -d "[email protected]"
/bin/zcat:exec gzip -cd "[email protected]"
0
SebMa

Архив Zip не является последовательным (поскольку он может содержать оглавление в конце файла), поэтому его трудно разархивировать в потоковом режиме. Попробуйте проверить, можете ли вы получить другой формат файла, например .tar.gz.

Если вы загружаете .Zip файл из GitHub, там почти всегда есть .tar.gz версия доступна.

Например,

Обратите внимание на шаблон? Просто замените .Zip с .tar.gz и ​​труба к | tar xzf -

0
rustyx