The goal is to read a zip file from stdin and uncompress to stdout.

Funzip works and is the solution I am looking for, the zip contains a single file, unfortunately funzip fails when the compressed file size is around 1GB or greater:

funzip error: invalid compressed data--length error

Update: I have discovered the above error may not indicate an actual error. Comparing two uncompressed files, one unzipped traditionally and the other through a pipe using funzip (with the above error written to stderr) the files are identical. I'd like to keep this open, so this can be confirmed or reported.

A related solution using python: Unzipping files that are flying in through a pipe

However this output is directed to a file.


Simply use zcat. For example:

cat file.zip | zcat

Please note that in the example above the first part (cat file.zip) is redundant, in the sense that you can simply issue zcat file.zip and have the same results. I included it only to show that zcat is capable to read from stdin

  • 1
    Wrong asnwer: zcat doesn't work with zip files! This answer should be downvoted. A solution can be found here using jar though: unix.stackexchange.com/questions/2690/… – Eric Apr 20 '18 at 11:53
  • @Eric on my CentOS 6 box, I surely can use zcat file.zip to show zipped files. For example: file services.zip returns services.zip: Zip archive data, at least v2.0 to extract, and I can zcat service.zip to show its content – shodanshok Apr 20 '18 at 21:18
  • Nope, it doesn't work on CentOS 6.9 when using a zip file that contains more than one file. I get gzip: zip file has more than one entry--rest ignored which is totally understandable since piping creates a stream and a stream is not seekable so zcat can't jump to the end of file to retrieve the files list. So in a nutshell zcat (actually gunzip since zcat calls it) doesn't work with zip files except when they contain only one file. Try it, you'lls see. – Eric Apr 22 '18 at 19:02
  • 1
    I was under the impression that OP really want to output to stdout a single zipped file, not an entire zip archive. After all, what is the point of showing multiple, concatenated files on stdout, when you can not tell were is start/end of each file? – shodanshok Apr 23 '18 at 5:21

Uncompressing (with redirect to file):

cat file.gz | gunzip -c - > file

Compressing (with redirect to file.gz)):

cat file | gzip -c - > file.gz
  • 1
    zip ang gzip are not the same thing. zip files stores the list of files at the end of the stream which makes it impractical for piping in while downloading. gzip doesn't have that limitation. This answer should be downvoted. – Eric Apr 20 '18 at 11:51

Repost of my answer:

BusyBox's unzip can take stdin and extract all the files to stdout. For example, when you use wget as stdin,

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

-p to extract files to pipe. The dash after is to use stdin as input.

You also can, (just like previous answer)

cat file.zip | busybox unzip -p -

But that's just redundant of unzip -p file.zip.

If your distro uses BusyBox by default (e.g. Alpine), just run unzip -p -.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.