it-swarm.cn

如何将wget的输出作为输入重定向到解压缩?

我必须从 link 下载文件。下载的文件是一个Zip文件,我必须将其解压缩到当前文件夹中。

通常,我会先下载它,然后运行unzip命令。

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

但是通过这种方式,我需要执行两个命令,等待第一个命令完成才能执行下一个命令,而且,我必须知道文件名temp.Zip分配给unzip

是否可以将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被执行了两次,并下载了两次文件。

142
Andrew-Dufresne

您必须将文件下载到临时文件,因为(引用解压缩手册页):

从标准输入中读取的档案尚不支持,但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(aka 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的输出传递到解压缩中。

从维基百科 “ Zip(文件格式)” 文章:

通过位于文件末尾的中央目录来识别Zip文件。

wget必须完全完成下载,然后解压缩才能执行任何工作,因此它们将按顺序运行,而不是像人们想象的那样交织在一起。

15
Bruce Ediger

正确的语法为:

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

但是由于错误(Debian上的Info-Zip)而无法使用:

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函数 ,以便设置文件偏移量以读取其中央目录记录的结尾 。它位于存档结构的末尾,需要读取文件列表(请参阅: Zip文件格式结构 )。因此,文件不能是FIFO,管道,终端设备或任何其他动态文件,因为lseek函数无法定位输入对象。

因此,您有以下解决方法:

  • 使用其他类型的压缩方式(例如tar.gz),
  • 您必须使用两个单独的命令,
  • 使用其他工具(如其他答案中所述),
  • 创建别名或函数以使用多个命令。
11
kenorb

转贴 我的答案

BusyBox的unzip可以使用stdin并提取所有文件。

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中只有一个文件,则可以使用zcatgunzip

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 "[email protected]"
/bin/zcat:exec gzip -cd "[email protected]"
0
SebMa

Zip存档不是顺序的(因为它可以在文件的末尾包含目录),因此很难对其进行流解压缩。尝试查看是否可以获得其他文件格式,例如.tar.gz

如果您要下载.Zip文件(来自GitHub,几乎总是.tar.gz版本可用。

例如,

注意到模式了吗?只需替换.Zip.tar.gz和管道到| tar xzf -

0
rustyx