52 votes

Décompression des fichiers qui sont envoyés dans un tuyau

Puis-je faire fonctionner unzip ou tout autre programme similaire sur la sortie standard? La situation est que je télécharge un fichier zip, qui est censé être décompressé à la volée.

Problème connexe : Comment puis-je rediriger un fichier téléchargé vers la sortie standard en bash?

0 votes

Cela semblait réalisable, mais il semble que ce soit seulement possible d'extraire un fichier zip et de le transmettre à une autre commande si le zip contient un seul fichier. Je voulais extraire un fichier spécifique d'un zip multi-fichier. Au lieu de transmettre, j'ai opté pour l'enchaînement de plusieurs commandes 'unzip file.zip /chemin/fichier && dostuff /chemin/fichier && rm -rf /chemin'. Bien que cela ne réponde pas à la question initiale et implique la création de fichiers temporaires, cela a satisfait mon besoin.

0 votes

Vérifiez pigz. Nous l'utilisons dans un tuyau. andrew.tumblr.com/post/2316602611

8voto

Saftever Points 211

Repost de ma réponse:

Le unzip de BusyBox peut prendre l'entrée standard 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 pour utiliser stdin comme entrée.

Vous pouvez même,

cat file.zip | busybox unzip -

Mais c'est simplement redondant de unzip file.zip.

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

0 votes

Il s'agit également d'une utilisation inutile de cat. La grande question, cependant, est la suivante : charge-t-il l'intégralité du fichier zip en mémoire ?

0 votes

@MichaelHampton: Ce n'est pas une utilisation inutile de cat. Avec myprog , _myprog_ est capable de rechercher dans f (son stdin). Avec `cat f | myprog`, _myprog_ est incapable de rechercher. Ainsi, l'utilisation de _cat_ prouve en réalité que la commande ne dépend pas de la recherche pour réussir, c'est-à-dire qu'elle traite son entrée comme un flux.

0 votes

unzip dans certaines versions de BusyBox (par exemple 1.27.2) ne prend pas en charge Zip64, il ne fonctionne donc que pour les fichiers membres inférieurs à 4 Go.

5voto

Adrian Points 151

Le moyen le plus simple couramment disponible pour faire cela est jar, qui supposera que STDIN est utilisé si vous ne lui passez aucun argument de fichier. Il prend également des arguments similaires au programme tar pour les opérations.

par exemple, lister le contenu d'une archive

curl https://my.example.com/file.zip | jar t

Alors que Java n'est pas toujours installé, sur ces machines où il l'est, jar est certainement la méthode la plus pratique pour le faire.

1 votes

Pour télécharger et extraire : curl https://my.example.com/file.zip | jar xv

0 votes

jar dans JDK (et OpenJDK) fonctionne, mais sur certains systèmes Linux, la commande jar est installée à partir du paquet fastjar, qui ne prend pas en charge de nombreuses fonctionnalités ZIP, y compris Zip64.

4voto

Dan Carley Points 24959

Il n'est pas possible avec Info-Zip qui est l'implémentation OSS la plus courante. Plus important encore, ce n'est pas recommandé en raison des structures des archives ZIP.

Si un changement de format est viable pour vous, envisagez d'utiliser tar(1) à la place. Il est tout à fait heureux avec les entrées/sorties en continu et, en fait, s'y attend par défaut.

De plus, vous pouvez souvent savoir si les applications attendent des entrées/sorties en continu en spécifiant "-" pour un nom de fichier. Info-Zip, comme vous pouvez l'imaginer, ne considère pas cela comme un argument valide.

4voto

Applefanboy Points 248

Dans zsh, vous pouvez faire ce qui suit :

unzip =( curl http://example.com/someZipFile.zip )

1 votes

Veuillez noter que cette commande télécharge l'intégralité de l'archive .zip avant de commencer à extraire le premier fichier membre. Par conséquent, elle ne réalise pas d'extraction en continu.

1voto

Jacob Ewing Points 366

J'avais en fait besoin de quelque chose un peu plus complexe - extraire un fichier spécifique s'il existe. La difficulté étant que le flux de fichier d'entrée peut ne pas être un fichier zip, et dans ce cas, je devais le faire passer à travers le tuyau. Voici ma solution (merci principalement à la solution de Jason R. Coombs)

python -c "import zipfile,sys,StringIO
data=sys.stdin.read()
try:
    z=zipfile.ZipFile(StringIO.StringIO(data))
    z.open(\"$1\")
    sys.stdout.write(z.read(\"$1\"))
except (RuntimeError, zipfile.BadZipfile):
    sys.stdout.write(data)"

J'ai enregistré cela sous le nom de fichier "effpoptp" (pas un nom simple) dans le dossier "/bin" sur ma machine donc le tester est comme suit :

cat defaultModel.mwb|effpoptp "document.mwb.xml"

Le but est de versionner les fichiers MySQL Workbench, où le fichier peut être le fichier xml nommé comme le fichier workbench, ou le fichier workbench complet.

1 votes

Veuillez noter que cette commande lit tout l'archive .zip en mémoire avant de commencer l'extraction du premier fichier membre. Ainsi, elle ne permet pas une extraction en continu.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X