Как перенаправить вывод 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`

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

  

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

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

110 голосов | спросил Andrew-Dufresne 4 +04002010-10-04T13:10:49+04:00312010bEurope/MoscowMon, 04 Oct 2010 13:10:49 +0400 2010, 13:10:49

5 ответов


75

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

  

Архивы читаются со стандартного ввода   пока не поддерживаются, за исключением   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
ответил tante 4 +04002010-10-04T13:33:38+04:00312010bEurope/MoscowMon, 04 Oct 2010 13:33:38 +0400 2010, 13:33:38
62

Это репортаж моего ответьте на аналогичный вопрос:

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

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

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

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

wget -qO- http://example.org/file.zip | bsdtar -xvf-
ответил ruario 16 PMpWed, 16 Apr 2014 22:00:07 +040000Wednesday 2014, 22:00:07
14

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

wget -qO- http://example.org/file.zip | jar xvf /dev/stdin
ответил Rory Hunter 11 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowFri, 11 Sep 2015 16:04:53 +0300 2015, 16:04:53
13

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

Из wikipedia «ZIP (формат файла)» :

  

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

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

ответил Bruce Ediger 4 +04002010-10-04T20:09:45+04:00312010bEurope/MoscowMon, 04 Oct 2010 20:09:45 +0400 2010, 20:09:45
5

Правильный синтаксис:

$ 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 , чтобы установить смещение файла в конце, чтобы прочитать его конец записи центрального каталога . Он находится в конце структуры архива и требуется прочитать список файлов (см. Структура формата файла Zip ). Поэтому файл не может быть FIFO, трубой, терминальным устройством или любой другой динамикой, потому что входной объект не может быть помещен функцией lseek.

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

  • используйте другой вид сжатия (например, tar.gz),
  • вам нужно использовать две отдельные команды,
  • используйте альтернативные инструменты (как предложено в других ответах),
  • создать псевдоним или функцию для использования нескольких команд.
ответил kenorb 15 J0000006Europe/Moscow 2016, 03:48:26

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132