web-dev-qa-db-fra.com

Comment rediriger la sortie de wget en entrée pour décompresser?

Je dois télécharger un fichier à partir de ce lien . Le téléchargement du fichier est un fichier Zip que je devrai décompresser dans le dossier courant.

Normalement, je le télécharge d'abord, puis j'exécute la commande de décompression.

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

Mais de cette façon, j'ai besoin d'exécuter deux commandes, d'attendre la fin de la première pour exécuter la suivante, aussi, je dois connaître le nom du fichier temp.Zip pour le donner à unzip.

Est-il possible de rediriger la sortie de wget vers unzip? Quelque chose comme

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

Mais ça n'a pas marché.

bash: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip: redirection ambiguë

De plus, wget a été exécuté deux fois et téléchargé le fichier deux fois.

142
Andrew-Dufresne

Vous devez télécharger vos fichiers dans un fichier temporaire, car (en citant la page de manuel de décompression):

Les archives lues à partir de l'entrée standard ne sont pas encore prises en charge, sauf avec funzip (et alors seul le premier membre de l'archive peut être extrait).

Rassemblez simplement les commandes:

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

Mais pour le rendre plus flexible, vous devriez probablement le mettre dans un script afin d'enregistrer de la frappe et pour vous assurer de ne pas écraser accidentellement quelque chose, vous pouvez utiliser la commande mktemp pour créer un nom de fichier sûr pour votre fichier temporaire:

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

Ceci est une rediffusion de ma réponse à une question similaire:

Le format de fichier Zip comprend un répertoire (index) à la fin de l'archive. Ce répertoire indique où, dans l'archive, chaque fichier est situé et permet ainsi un accès rapide et aléatoire, sans lire l'archive entière.

Cela semblerait poser un problème lors de la tentative de lecture d'une archive Zip via un canal, dans la mesure où l'index n'est accessible qu'à la toute fin et que les membres individuels ne peuvent être extraits correctement qu'après que le fichier a été entièrement lu et n'est plus disponible . En tant que tel, il ne semble pas surprenant que la plupart des décompresseurs Zip échouent simplement lorsque l'archive est fournie via un canal.

Le répertoire à la fin de l'archive n'est pas seulement l'emplacement où les méta-informations du fichier sont stockées dans l'archive. De plus, les entrées individuelles incluent également ces informations dans un en-tête de fichier local, à des fins de redondance.

Bien que tous les décompresseurs Zip n'utilisent pas les en-têtes de fichiers locaux lorsque l'index n'est pas disponible, les frontaux tar et cpio de libarchive (aka bsdtar et bsdcpio) peuvent et vont le faire lors de la lecture d'un tube, ce qui signifie que ce qui suit est possible:

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

Si le JDK est installé, vous pouvez utiliser jar:

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

Je ne pense pas que vous souhaitiez même déranger la sortie de wget en dézippant.

Extrait du wikipedia "Zip (format de fichier)" article:

Un fichier Zip est identifié par la présence d'un répertoire central situé à la fin du fichier.

wget doit terminer complètement le téléchargement avant que la décompression ne puisse faire aucun travail, donc ils s'exécutent séquentiellement, pas entrelacés comme on pourrait le penser.

15
Bruce Ediger

La syntaxe appropriée serait:

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

mais cela ne fonctionnera pas, à cause de l'erreur ( Info-Zip sur 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 sur BSD/OS X:

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

En effet, les outils Zip standard utilisent principalement fonction lseek afin de définir le décalage du fichier à la fin pour lire son fin de central enregistrement de répertoire . Il est situé à la fin de la structure de l'archive et il est nécessaire de lire la liste des fichiers (voir: Structure de format de fichier Zip ). Par conséquent, le fichier ne peut pas être FIFO, pipe, périphérique terminal ou toute autre dynamique, car l'objet d'entrée ne peut pas être positionné par la fonction lseek.

Vous disposez donc des solutions de contournement suivantes:

  • utiliser différents types de compression (par exemple tar.gz),
  • vous devez utiliser deux commandes distinctes,
  • utiliser des outils alternatifs (comme suggéré dans d'autres réponses),
  • créer un alias ou une fonction pour utiliser plusieurs commandes.
11
kenorb

Republication de ma réponse :

unzip de BusyBox peut prendre stdin et extraire tous les fichiers.

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

Le tiret après unzip est d'utiliser stdin comme entrée.

Vous pouvez même,

cat file.Zip | busybox unzip -

Mais c'est tout simplement redondant de unzip file.Zip.

Si votre distribution utilise BusyBox par défaut (par exemple Alpine), exécutez simplement unzip -.

11
Saftever

S'il n'y a qu'un seul fichier dans Zip, vous pouvez utiliser zcat ou gunzip:

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

FYI: Voici les définitions de gunzip et zcat sur mon système:

$ grep ^exec $(which gunzip zcat)
/bin/gunzip:exec gzip -d "$@"
/bin/zcat:exec gzip -cd "$@"
0
SebMa

Une archive Zip n'est pas séquentielle (car elle peut avoir la table des matières à la fin du fichier), il est donc difficile de la décompresser en continu. Essayez de voir si vous pouvez obtenir un autre format de fichier, comme .tar.gz.

Si vous téléchargez un .Zip fichier de GitHub, il y a presque toujours un .tar.gz version disponible.

Par exemple,

Remarquez le motif? Remplacez simplement .Zip avec .tar.gz et diriger vers | tar xzf -

0
rustyx