it-swarm-pt.tech

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

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

Normalmente, eu deveria baixá-lo primeiro e depois executar o comando descompactar.

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

Mas, dessa forma, preciso executar dois comandos, aguardar a conclusão do primeiro para executar o próximo, além disso, devo 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 deu certo.

bash: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip: redirecionamento ambíguo

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

142
Andrew-Dufresne

Você precisa baixar seus arquivos para um arquivo temporário, porque (citando a página de manual descompactar):

Os arquivos lidos a partir da entrada padrão ainda não são suportados, exceto com o funzip (e somente o primeiro membro do arquivo pode ser extraído).

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 inseri-lo em um script, para salvar algumas digitações e, para garantir que não substitua acidentalmente algo, use 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
105
tante

Esta é uma repostagem de minha resposta para uma pergunta semelhante:

O formato do arquivo Zip inclui um diretório (índice) no final do arquivo morto. Esse diretório diz onde, dentro do arquivo, cada arquivo está localizado e, portanto, permite acesso rápido e aleatório, sem a leitura de todo o arquivo.

Isso parece representar um problema ao tentar ler um arquivo Zip por meio de um canal, pois o índice não é acessado até o final e, portanto, os membros individuais não podem ser extraídos corretamente até depois que o arquivo foi totalmente lido e não está mais disponível . Como tal, não surpreende que a maioria dos descompressores Zip simplesmente falhe quando o arquivo é fornecido através de um tubo.

O diretório no final do arquivo morto não é o local apenas onde as metainformações do arquivo são armazenadas no arquivo morto. 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 estiver indisponível, os front-ends tar e cpio para libarchive (também conhecidos como bsdtar e bsdcpio) podem e serão ao ler um pipe, o que significa que é possível o seguinte:

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

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

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

Eu acho que você nem quer incomodar a saída do wget da tubulação para descompactar.

Da wikipedia "Zip (formato de arquivo)" artigo:

Um arquivo Zip é identificado pela presença de um diretório central localizado no final do arquivo.

o wget precisa finalizar completamente o download antes que o descompacte possa executar qualquer trabalho, para que eles sejam executados seqüencialmente, não entrelaçados como se poderia imaginar.

15
Bruce Ediger

A sintaxe adequada seria:

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

mas não funcionará, devido ao erro ( Info-Zip no 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 Zip padrão estão usando principalmente lseek function para definir o deslocamento do arquivo no final para ler seu final da central registro de diretório . Ele está localizado no final da estrutura do arquivo e é necessário ler a lista dos arquivos (consulte: Estrutura do formato do arquivo zip ). Portanto, o arquivo não pode ser FIFO, canal, dispositivo terminal ou qualquer outra dinâmica, porque o objeto de entrada não pode ser posicionado pela função lseek.

Então você tem as seguintes soluções alternativas:

  • use diferentes tipos de compactação (por exemplo, tar.gz),
  • você tem que usar dois comandos separados,
  • use ferramentas alternativas (como sugerido em outras respostas),
  • crie um alias ou função para usar vários comandos.
11
kenorb

Repostar de minha resposta :

O unzip do BusyBox pode levar o 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ê também pode,

cat file.Zip | busybox unzip -

Mas isso é apenas redundante de unzip file.Zip.

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

11
Saftever

Se houver apenas um arquivo no Zip, você poderá usar zcat ou gunzip:

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

FYI: Aqui estão as definições de gunzip e zcat no meu sistema:

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

Um arquivo Zip não é seqüencial (já que pode ter o índice no final do arquivo), por isso é difícil descompactá-lo por streaming. Tente ver se você pode obter outro formato de arquivo, como .tar.gz.

Se você estiver baixando um .Zip do GitHub, quase sempre existe um .tar.gz versão disponível.

Por exemplo,

Observe o padrão? Apenas substitua .Zip com .tar.gz e canalize para | tar xzf -

0
rustyx