Como redirecionar a saída do wget como entrada para descompactar?

117

Eu tenho que baixar um arquivo deste link . O download do arquivo é um arquivo zip que eu terei que descompactar na pasta atual.

Normalmente, eu faço o download primeiro e, em seguida, executo o comando unzip.

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

Mas desta forma, preciso executar dois comandos, aguardar a conclusão do primeiro para executar o próximo, também, preciso saber o nome do arquivo temp.zip para dar a unzip .

É possível redirecionar a saída de wget para unzip ? Algo como

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

Mas não funcionou.

bash: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip: ambiguous redirect

Além disso, wget foi executado duas vezes e baixou o arquivo duas vezes.

    
por Andrew-Dufresne 04.10.2010 / 11:10

6 respostas

84

Você tem que baixar seus arquivos para um arquivo temporário, porque (citando a página man unzip):

Archives read from standard input are not yet supported, except with funzip (and then only the first member of the archive can be extracted).

Basta reunir os comandos:

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

Mas para torná-lo mais flexível, você provavelmente deve colocá-lo em um script para salvar algumas digitação e para garantir que você não sobrescreva acidentalmente algo que possa usar o comando mktemp para criar um nome de arquivo seguro para o seu arquivo temporário:

#!/bin/bash
TMPFILE='mktemp'
PWD='pwd'
wget "$1" -O $TMPFILE
unzip -d $PWD $TMPFILE
rm $TMPFILE
    
por 04.10.2010 / 11:33
68

Este é um repost do meu responda a uma pergunta semelhante:

O formato de arquivo ZIP inclui um diretório (índice) no final do arquivo. Este diretório diz onde, dentro do arquivo, cada arquivo está localizado e, assim, permite acesso rápido e aleatório, sem ler o arquivo inteiro.

Isto parece representar um problema ao tentar ler um arquivo ZIP através de um pipe, em que o índice não é acessado até o final e assim membros individuais não podem ser corretamente extraídos até depois que o arquivo tenha sido lido inteiramente e seja não está mais disponível. Como tal, não parece surpreendente que a maioria dos descompactadores ZIP simplesmente falhe quando o arquivo é fornecido através de um pipe.

O diretório no final do arquivo não é o único local onde as informações meta do arquivo são armazenadas no arquivo. Além disso, entradas individuais também incluem essas informações em um cabeçalho de arquivo local, para fins de redundância.

Embora nem todo descompactador ZIP use cabeçalhos de arquivos locais quando o índice está indisponível, o front end tar e cpio para libarchive (também conhecido como bsdtar e bsdcpio) pode e vai fazê-lo ao ler um pipe , o que significa que o seguinte é possível:

wget -qO- http://example.org/file.zip | bsdtar -xvf-
    
por 16.04.2014 / 20:00
17

Se você tiver o JDK instalado, poderá usar jar :

wget -qO- http://example.org/file.zip | jar xvf /dev/stdin
    
por 11.09.2015 / 15:04
14

Eu não acho que você queira incomodar a saída do wget no unzip.

Na Wikipédia, o artigo "ZIP (formato de arquivo)" :

A ZIP file is identified by the presence of a central directory located at the end of the file.

wget tem que terminar completamente o download antes que o unzip possa fazer qualquer trabalho, então eles são executados sequencialmente, não entrelaçados como se poderia pensar.

    
por 04.10.2010 / 18:09
7

A sintaxe correta seria:

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

mas não funciona, por causa do erro ( Info-ZIP em 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.

ou no BSD / OS X:

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

Isso ocorre porque as ferramentas padrão de zip usam principalmente lseek function para definir o deslocamento do arquivo no final para ler seu fim do registro do diretório central . Ele está localizado no final da estrutura do arquivo e é necessário ler a lista dos arquivos (consulte: Zip estrutura de formato de arquivo ). Portanto, o arquivo não pode ser FIFO, pipe, dispositivo de terminal ou qualquer outra dinâmica, porque o objeto de entrada não pode ser posicionado pela função lseek .

Você tem as seguintes soluções alternativas:

  • usam diferentes tipos de compactação (por exemplo, tar.gz ),
  • você precisa usar dois comandos separados,
  • use ferramentas alternativas (conforme sugerido em outras respostas),
  • crie um alias ou função para usar vários comandos.
por 15.06.2016 / 02:48
2

Repost de minha resposta :

O unzip do BusyBox pode pegar stdin e extrair todos os arquivos.

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

O traço após unzip é usar stdin como entrada.

Você pode até mesmo,

cat file.zip | busybox unzip -

Mas isso é apenas redundante de unzip file.zip .

Se a sua distro usar o BusyBox por padrão (por exemplo, Alpine), basta executar unzip - .

    
por 11.10.2018 / 14:10