it-swarm-vi.com

Làm thế nào để chuyển hướng đầu ra của wget như đầu vào để giải nén?

Tôi phải tải xuống một tệp từ đây link . Tải xuống tệp là một tệp Zip mà tôi sẽ phải giải nén trong thư mục hiện tại.

Thông thường, tôi sẽ tải xuống trước, sau đó chạy lệnh giải nén.

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

Nhưng theo cách này, tôi cần thực thi hai lệnh, chờ hoàn thành lệnh đầu tiên để thực thi lệnh tiếp theo, đồng thời, tôi phải biết tên của tệp temp.Zip để đưa nó cho unzip.

Có thể chuyển hướng đầu ra của wget sang unzip không? Cái gì đó như

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

Nhưng nó không hoạt động.

bash: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.Zip: Chuyển hướng mơ hồ

Ngoài ra, wget đã thực hiện hai lần và tải xuống tệp hai lần.

142
Andrew-Dufresne

Bạn phải tải các tệp của mình xuống tệp tạm thời, bởi vì (trích dẫn trang man giải nén):

Lưu trữ đọc từ đầu vào tiêu chuẩn chưa được hỗ trợ, ngoại trừ với funzip (và sau đó chỉ có thể trích xuất thành viên đầu tiên của kho lưu trữ).

Chỉ cần mang các lệnh lại với nhau:

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

Nhưng để làm cho nó linh hoạt hơn, có lẽ bạn nên đặt nó vào một tập lệnh để bạn lưu một số thao tác gõ và để đảm bảo bạn không vô tình ghi đè lên một cái gì đó bạn có thể sử dụng lệnh mktemp để tạo một tên tệp an toàn cho tệp tạm thời của bạn:

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

Đây là một repost của câu trả lời của tôi cho một câu hỏi tương tự:

Định dạng tệp Zip bao gồm một thư mục (chỉ mục) ở cuối kho lưu trữ. Thư mục này cho biết vị trí, trong kho lưu trữ, mỗi tệp được đặt và do đó cho phép truy cập nhanh, ngẫu nhiên mà không cần đọc toàn bộ tệp lưu trữ.

Điều này có vẻ gây ra vấn đề khi cố đọc lưu trữ Zip qua đường ống, trong đó chỉ mục không được truy cập cho đến khi kết thúc và do đó, các thành viên riêng lẻ không thể được trích xuất chính xác cho đến khi tệp đã được đọc hoàn toàn và không còn khả dụng . Do đó, có vẻ không ngạc nhiên khi hầu hết các bộ giải nén Zip chỉ đơn giản là thất bại khi kho lưu trữ được cung cấp qua một đường ống.

Thư mục ở cuối kho lưu trữ không phải là vị trí chỉ nơi lưu trữ thông tin meta tệp trong kho lưu trữ. Ngoài ra, các mục riêng lẻ cũng bao gồm thông tin này trong tiêu đề tệp cục bộ, cho mục đích dự phòng.

Mặc dù không phải mọi trình giải nén Zip sẽ sử dụng các tiêu đề tệp cục bộ khi chỉ mục không khả dụng, mặt trước tar và cpio kết thúc thành libarchive (còn gọi là bsdtar và bsdcpio) có thể và sẽ làm như vậy khi đọc qua một đường ống, có nghĩa là có thể sau đây:

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

Nếu bạn đã cài đặt JDK, bạn có thể sử dụng jar:

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

Tôi không nghĩ rằng bạn thậm chí muốn làm phiền đầu ra của đường ống vào giải nén.

Từ wikipedia "Zip (định dạng tệp)" bài viết:

Một tệp Zip được xác định bởi sự hiện diện của một thư mục trung tâm nằm ở cuối tệp.

wget phải hoàn thành việc tải xuống trước khi giải nén có thể thực hiện bất kỳ công việc nào, vì vậy chúng chạy tuần tự, không đan xen như người ta nghĩ.

15
Bruce Ediger

Cú pháp thích hợp sẽ là:

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

nhưng nó không hoạt động, vì lỗi ( Info-Zip trên Debian ):

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.

hoặc trên BSD/OS X:

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

Điều này là do các công cụ Zip tiêu chuẩn chủ yếu sử dụng lseek function để đặt phần bù tệp ở cuối để đọc phần cuối của phần trung tâm bản ghi thư mục . Nó nằm ở cuối cấu trúc lưu trữ và cần phải đọc danh sách các tệp (xem: Cấu trúc định dạng tệp Zip ). Do đó, tệp không thể là FIFO, ống, thiết bị đầu cuối hoặc bất kỳ động nào khác, vì đối tượng đầu vào không thể được định vị bằng hàm lseek.

Vì vậy, bạn có cách giải quyết sau đây:

  • sử dụng loại nén khác nhau (ví dụ: tar.gz),
  • bạn phải sử dụng hai lệnh riêng biệt
  • sử dụng các công cụ thay thế (như được đề xuất trong các câu trả lời khác),
  • tạo một bí danh hoặc hàm để sử dụng nhiều lệnh.
11
kenorb

Đăng lại câu trả lời của tôi :

BusyBox's unzip có thể lấy stdin và giải nén tất cả các tệp.

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

Dấu gạch ngang sau unzip là sử dụng stdin làm đầu vào.

Bạn có thể,

cat file.Zip | busybox unzip -

Nhưng đó chỉ là dư thừa của unzip file.Zip.

Nếu distro của bạn sử dụng BusyBox theo mặc định (ví dụ: Alpine), chỉ cần chạy unzip -.

11
Saftever

Nếu chỉ có một tệp trong Zip, bạn có thể sử dụng zcat hoặc gunzip:

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

FYI: Dưới đây là định nghĩa của gunzipzcat trên hệ thống của tôi:

$ grep ^exec $(which gunzip zcat)
/bin/gunzip:exec gzip -d "[email protected]"
/bin/zcat:exec gzip -cd "[email protected]"
0
SebMa

Lưu trữ Zip không tuần tự (vì nó có thể có mục lục ở cuối tệp) nên rất khó để giải nén luồng. Hãy thử xem bạn có thể lấy định dạng tệp khác không, như .tar.gz.

Nếu bạn đang tải xuống tệp .Zip Từ GitHub, hầu như luôn có sẵn phiên bản .tar.gz.

Ví dụ,

Chú ý mẫu? Chỉ cần thay thế .Zip Bằng .tar.gz Và chuyển thành | tar xzf -

0
rustyx