CLOVER🍀

That was when it all began.

標準入力からunzipしたい

tarコマンドでは、-f -を引数にすることで標準入力から読み込んでアーカイブを展開することができます。

たとえば、Apache Tomcatのtar.gzファイルのダウンロードを例にすると、こんな感じで。
※ curlの-o -で標準出力に書き出します

$ curl -sL -o - https://ftp.tsukuba.wide.ad.jp/software/apache/tomcat/tomcat-9/v9.0.39/bin/apache-tomcat-9.0.39.tar.gz | \
   tar zxvf -

これと同じことを、zipファイルの場合にどうすればいいか?という話。

unzipでは、-で標準入力を取れないのでうまくいきません。

$ curl  -sL -o - https://ftp.tsukuba.wide.ad.jp/software/apache/tomcat/tomcat-9/v9.0.39/bin/apache-tomcat-9.0.39.zip | \
  unzip -
UnZip 6.00 of 20 April 2009, by Debian. Original by Info-ZIP.

Usage: unzip [-Z] [-opts[modifiers]] file[.zip] [list] [-x xlist] [-d exdir]
  Default action is to extract files in list, except those in xlist, to exdir;
  file[.zip] may be a wildcard.  -Z => ZipInfo mode ("unzip -Z" for usage).

  -p  extract files to pipe, no messages     -l  list files (short format)
  -f  freshen existing files, create none    -t  test compressed archive data
  -u  update files, create if necessary      -z  display archive comment only
  -v  list verbosely/show version info       -T  timestamp archive to latest
  -x  exclude files that follow (in xlist)   -d  extract files into exdir
modifiers:
  -n  never overwrite existing files         -q  quiet mode (-qq => quieter)
  -o  overwrite files WITHOUT prompting      -a  auto-convert any text files
  -j  junk paths (do not make directories)   -aa treat ALL files as text
  -U  use escapes for all non-ASCII Unicode  -UU ignore any Unicode fields
  -C  match filenames case-insensitively     -L  make (some) names lowercase
  -X  restore UID/GID info                   -V  retain VMS version numbers
  -K  keep setuid/setgid/tacky permissions   -M  pipe through "more" pager
  -O CHARSET  specify a character encoding for DOS, Windows and OS/2 archives
  -I CHARSET  specify a character encoding for UNIX and other archives

See "unzip -hh" or unzip.txt for more help.  Examples:
  unzip data1 -x joe   => extract all files except joe from zipfile data1.zip
  unzip -p foo | more  => send contents of foo.zip via pipe into program more
  unzip -fo foo ReadMe => quietly replace existing ReadMe if archive file newer

busybox unzipであれば-が使えます。

$ curl  -sL -o - https://ftp.tsukuba.wide.ad.jp/software/apache/tomcat/tomcat-9/v9.0.39/bin/apache-tomcat-9.0.39.zip | \
  busybox unzip -

ただ、いつもうまくいくわけではなくストリーミングになるとダメだったりします。

unzip: zip flag 8 (streaming) is not supported

さらに別解としては、jarコマンドで/dev/stdinをファイル名に指定すると展開できたりします。

$ curl  -sL -o - https://ftp.tsukuba.wide.ad.jp/software/apache/tomcat/tomcat-9/v9.0.39/bin/apache-tomcat-9.0.39.zip | \
  jar -xvf /dev/stdin

jarコマンドだと、busybox unzipで失敗するケースもうまくいったりします。

が、無難には1度ファイルにした方がいいんでしょうねぇ。

あと、zip拡張子がある場合は、tar.gz拡張子でも提供されていることが多いので、ファイルダウンロードしてそのまま展開…
というような今回の例のようなケースでは、tar.gzの存在を探る方が良いでしょうね。