And*_*sne 169 command-line io-redirection
我必须从这个链接下载一个文件。文件下载是一个 zip 文件,我必须将其解压缩到当前文件夹中。
通常,我会先下载它,然后运行 unzip 命令。
$ wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip
$ unzip temp.zip
Run Code Online (Sandbox Code Playgroud)
但是这样,我需要执行两个命令,等待第一个执行完成后执行下一个,而且,我必须知道文件的名称temp.zip才能将其提供给unzip.
是否可以将输出重定向wget到unzip?就像是
$ unzip < `wget http://www.vim.org/scripts/download_script.php?src_id=11834`
Run Code Online (Sandbox Code Playgroud)
但它没有用。
bash
wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zip:: 不明确的重定向
此外,wget被执行了两次,并下载了两次文件。
tan*_*nte 128
您必须将文件下载到临时文件,因为(引用解压缩手册页):
尚不支持从标准输入读取的档案,除了 funzip(然后只能提取档案的第一个成员)。
只需将命令放在一起:
wget "http://www.vim.org/scripts/download_script.php?src_id=11834" -O temp.zip
unzip temp.zip
rm temp.zip
Run Code Online (Sandbox Code Playgroud)
但是为了使其更灵活,您可能应该将其放入脚本中,以便您节省一些输入,并确保您不会意外覆盖某些内容,您可以使用该mktemp命令为您的临时文件创建一个安全的文件名:
#!/bin/bash
TMPFILE=`mktemp`
PWD=`pwd`
wget "$1" -O $TMPFILE
unzip -d $PWD $TMPFILE
rm $TMPFILE
Run Code Online (Sandbox Code Playgroud)
小智 104
ZIP 文件格式在存档末尾包含一个目录(索引)。这个目录说明了每个文件在存档中的位置,因此可以快速、随机地访问,而无需读取整个存档。
当尝试通过管道读取 ZIP 存档时,这似乎会造成问题,因为直到最后才访问索引,因此在文件完全读取并且不再可用之前无法正确提取单个成员. 因此,当通过管道提供存档时,大多数 ZIP 解压缩器只会失败,这似乎并不奇怪。
存档末尾的目录不是文件元信息存储在存档中的唯一位置。此外,出于冗余目的,各个条目还在本地文件头中包含此信息。
虽然不是每个 ZIP 解压缩器在索引不可用时都会使用本地文件头,但 libarchive(又名 bsdtar 和 bsdcpio)的 tar 和 cpio 前端在通过管道读取时可以并且将会这样做,这意味着以下是可能的:
wget -qO- http://example.org/file.zip | bsdtar -xvf-
Run Code Online (Sandbox Code Playgroud)
小智 29
如果您安装了 JDK,则可以使用jar:
wget -qO- http://example.org/file.zip | jar xvf /dev/stdin
Run Code Online (Sandbox Code Playgroud)
小智 21
转贴我的回答:
BusyBoxunzip可以使用标准输入并提取所有文件。
wget -qO- http://downloads.wordpress.org/plugin/akismet.2.5.3.zip | busybox unzip -
Run Code Online (Sandbox Code Playgroud)
后面的破折号unzip是使用 stdin 作为输入。
你甚至可以,
cat file.zip | busybox unzip -
Run Code Online (Sandbox Code Playgroud)
但这只是多余的unzip file.zip。
如果您的发行版默认使用 BusyBox(例如 Alpine),只需运行unzip -.
Bru*_*ger 20
我认为您甚至不想费心将 wget 的输出传输到解压缩中。
来自维基百科“ZIP(文件格式)”文章:
ZIP 文件通过位于文件末尾的中央目录来标识。
wget 必须在 unzip 执行任何工作之前完全完成下载,因此它们按顺序运行,而不是像人们想象的那样交织在一起。
ken*_*orb 17
正确的语法是:
$ unzip <(curl -sL https://www.winpcap.org/archive/1.0-docs.zip)
Run Code Online (Sandbox Code Playgroud)
但它不起作用,因为错误(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.
Run Code Online (Sandbox Code Playgroud)
或在 BSD/OS X 上:
Trying to read large file (> 2 GiB) without large file support
Run Code Online (Sandbox Code Playgroud)
这是因为标准的 zip 工具主要使用lseek函数来设置文件末尾的偏移量以读取其中央目录记录的末尾。它位于存档结构的末尾,需要读取文件列表(请参阅:Zip 文件格式结构)。因此文件不能是 FIFO、管道、终端设备或任何其他动态文件,因为lseek函数无法定位输入对象。
因此,您有以下解决方法:
tar.gz),