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.
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
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-
Si le JDK est installé, vous pouvez utiliser jar
:
wget -qO- http://example.org/file.Zip | jar xvf /dev/stdin
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.
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:
tar.gz
),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 -
.
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 "$@"
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 -