web-dev-qa-db-ja.com

wgetの出力をunzipへの入力としてリダイレクトするにはどうすればよいですか?

これからファイルをダウンロードする必要があります link 。ファイルのダウンロードはZipファイルで、現在のフォルダーで解凍する必要があります。

通常は、最初にダウンロードしてから、unzipコマンドを実行します。

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

しかし、この方法では、2つのコマンドを実行し、最初のコマンドの完了を待って次のコマンドを実行する必要があります。また、ファイルの名前を知っている必要がありますtemp.Zipunzipに渡します。

wgetの出力をunzipにリダイレクトできますか?何かのようなもの

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

しかし、それはうまくいきませんでした。

bash:wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip:あいまいなリダイレクト

また、wgetは2回実行され、ファイルを2回ダウンロードしました。

142
Andrew-Dufresne

ファイルを一時ファイルにダウンロードする必要があります。理由は(unzipのmanページを引用しているため):

Funzipを除いて、標準入力から読み取ったアーカイブはまだサポートされていません(アーカイブの最初のメンバーのみを抽出できます)。

コマンドをまとめるだけです。

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

しかし、より柔軟にするために、おそらくスクリプトに入力して、いくつかの入力を節約し、誤って何かを上書きしないようにするために、mktempコマンドを使用して安全なファイル名を作成することができます。あなたの一時ファイル:

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

これは、同様の質問に対する 私の答え の再投稿です。

Zipファイル形式には、アーカイブの最後にディレクトリ(インデックス)が含まれています。このディレクトリは、アーカイブ内の各ファイルの場所を示しているため、アーカイブ全体を読み取ることなく、すばやくランダムにアクセスできます。

これは、パイプを介してZipアーカイブを読み取ろうとすると問題が発生するように見えます。インデックスは最後までアクセスされないため、ファイルが完全に読み取られて使用できなくなるまで、個々のメンバーを正しく抽出できません。 。そのため、アーカイブがパイプを介して提供される場合、ほとんどのZipデコンプレッサが単に失敗するのは当然のことです。

アーカイブの最後のディレクトリは、ファイルメタ情報がアーカイブに格納されるonlyの場所ではありません。さらに、冗長性を確保するために、個々のエントリのローカルファイルヘッダーにもこの情報が含まれています。

インデックスが利用できない場合、すべてのZipデコンプレッサがローカルファイルヘッダーを使用するわけではありませんが、tarおよびcpioフロントエンドはlibarchive(別名bsdtarおよびbsdcpio)にcanおよびwillパイプを介して読み取る場合は、次のことが可能です。

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

JDKがインストールされている場合は、jarを使用できます。

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

Wgetの出力をunzipにパイピングしたくもないでしょう。

ウィキペディアから "Zip(ファイル形式)" 記事:

Zipファイルは、ファイルの最後にある中央ディレクトリの存在によって識別されます。

wgetは、unzipが作業を行う前にダウンロードを完全に完了する必要があるため、思ったように織り交ぜられるのではなく、順次実行されます。

15
Bruce Ediger

適切な構文は次のとおりです。

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

しかし、エラー(Info-ZiponDebian)のため、機能しません:

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.

またはBSD/OS Xの場合:

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

これは、標準のZipツールが主に lseek function を使用して、中央ディレクトリレコードのの終わりを読み取るためにファイルオフセットを最後に設定するためです。これはアーカイブ構造の最後にあり、ファイルのリストを読み取るために必要です(参照: Zipファイル形式の構造 )。したがって、入力オブジェクトをlseek関数で配置できないため、ファイルをFIFO、パイプ、端末デバイス、またはその他の動的なファイルにすることはできません。

したがって、次の回避策があります。

  • 別の種類の圧縮を使用します(例:tar.gz)、
  • 2つの別々のコマンドを使用する必要があります。
  • (他の回答で提案されている)代替ツールを使用する
  • 複数のコマンドを使用するには、エイリアスまたは関数を作成します。
11
kenorb

私の答え の再投稿:

BusyBoxのunzipは、標準入力を取り、すべてのファイルを抽出できます。

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

unzipの後のダッシュは、stdinを入力として使用するためのものです。

あなたもできます

cat file.Zip | busybox unzip -

しかし、それはunzip file.Zipの冗長です。

ディストリビューションがデフォルトでBusyBoxを使用している場合(Alpineなど)、unzip -を実行します。

11
Saftever

Zipにファイルが1つしかない場合は、zcatまたはgunzipを使用できます。

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

参考:システムでのgunzipzcatの定義は次のとおりです。

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

Zipアーカイブはシーケンシャルではないため(ファイルの最後に目次がある場合があるため)、ストリームを解凍するのは困難です。 .tar.gzなどの別のファイル形式を取得できるかどうかを確認してください。

GitHubから.Zipファイルをダウンロードしている場合、ほとんどの場合.tar.gzバージョンが利用可能です。

例えば、

パターンに気づきましたか? .Zip.tar.gzに置き換え、| tar xzf -にパイプするだけです

0
rustyx