Bagaimana cara mengarahkan output wget sebagai input ke unzip?

131

Saya harus mengunduh file dari tautan ini . Unduhan file adalah file zip yang harus saya unzip di folder saat ini.

Biasanya, saya akan mengunduhnya terlebih dahulu, kemudian jalankan perintah unzip.

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

Tetapi dengan cara ini, saya perlu menjalankan dua perintah, menunggu penyelesaian yang pertama untuk mengeksekusi yang berikutnya, juga, saya harus tahu nama file temp.zipuntuk memberikannya unzip.

Apakah mungkin untuk mengarahkan output wgetke unzip? Sesuatu seperti

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

Tapi itu tidak berhasil.

bash:: wget http://www.vim.org/scripts/download_script.php?src_id=11834 -O temp.zippengalihan ambigu

Juga, wgetdieksekusi dua kali, dan mengunduh file dua kali.

Andrew-Dufresne
sumber
Pada contoh terakhir, wget mungkin dieksekusi dua kali karena? adalah karakter khusus di shell. Memasukkan URL ke "" seharusnya membantu.
p-static
Utas ini sepertinya punya solusi. Belum mencobanya sendiri. serverfault.com/questions/26474/…

Jawaban:

96

Anda harus mengunduh file ke file temp, karena (mengutip halaman unzip man):

Arsip yang dibaca dari input standar belum didukung, kecuali dengan funzip (dan kemudian hanya anggota arsip pertama yang dapat diekstraksi).

Satukan saja perintah-perintahnya:

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

Tetapi untuk membuatnya lebih fleksibel Anda mungkin harus memasukkannya ke dalam skrip sehingga Anda menyimpan beberapa pengetikan dan untuk memastikan Anda tidak secara tidak sengaja menimpa sesuatu Anda bisa menggunakan mktempperintah untuk membuat nama file yang aman untuk file temp Anda:

#!/bin/bash
TMPFILE=`mktemp`
PWD=`pwd`
wget "$1" -O $TMPFILE
unzip -d $PWD $TMPFILE
rm $TMPFILE
tante
sumber
Apakah wget file.zip && unzip file.zipsama wget file.zip; unzip file.zipatau lebih disukai daripada yang lain? Terima kasih :)
jaggedsoft
7
@NextLocal wget && unzipakan berjalan unzip hanya jika wget berhasil. wget ; unzipakan tetap menjalankan unzip, mungkin menunjuk ke file yang tidak ada.
temoto
funzip adalah jawaban yang saya cari. Paket Terraform (karena alasan tertentu) adalah biner sebagai satu file dalam arsip zip jadi ini sempurna bagi saya.
Asfand Qazi
75

Ini adalah repost dari jawaban saya untuk pertanyaan serupa:

Format file ZIP termasuk direktori (indeks) di akhir arsip. Direktori ini mengatakan di mana, di dalam arsip, setiap file berada dan dengan demikian memungkinkan akses cepat dan acak, tanpa membaca seluruh arsip.

Ini akan muncul untuk menimbulkan masalah ketika mencoba membaca arsip ZIP melalui pipa, di mana indeks tidak diakses sampai akhir sehingga anggota individu tidak dapat diekstraksi dengan benar sampai setelah file telah sepenuhnya dibaca dan tidak lagi tersedia . Dengan demikian tampaknya tidak mengejutkan bahwa sebagian besar dekompresi ZIP gagal ketika arsip dipasok melalui pipa.

Direktori di akhir arsip bukan satu - satunya lokasi di mana informasi meta file disimpan dalam arsip. Selain itu, setiap entri juga menyertakan informasi ini di header file lokal, untuk tujuan redundansi.

Meskipun tidak setiap dekompresor ZIP akan menggunakan header file lokal ketika indeks tidak tersedia, tar dan cpio depan berakhir ke libarchive (alias bsdtar dan bsdcpio) dapat dan akan melakukannya saat membaca melalui pipa, yang berarti bahwa hal berikut mungkin terjadi:

wget -qO- http://example.org/file.zip | bsdtar -xvf-
ruario
sumber
1
Ini luar biasa! Saya akan mencatat bahwa tar memberi saya beberapa peringatan tentang data yang tidak terkompresi menjadi ukuran yang salah (diharapkan 0), tetapi file-file itu sendiri tampaknya tidak rusak. Menebak ini karena kurangnya indeks.
Wyatt8740
1
Saya memiliki file .zip-file di sini yang berisi file dengan izin yang dapat dieksekusi. Ketika saya mengunduh dan bsdtarmengirim pipa ke , bit exec bisa dibuang. Ketika saya mengunduh ke disk dan mengekstrak dengan bsdtaratau unzipkemudian, bit exec merasa terhormat.
Golar Ramblar
//, @GolarRamblar, apakah kamu pernah tahu mengapa?
Nathan Basanese
1
@NathanBasanese: inilah jawabannya. Singkatnya: Arsip ZIP memiliki dua tempat di mana ia menyimpan informasi tersebut, yang bisa tidak konsisten, dan tergantung apakah file yang bsdtardibuka dapat dicari atau tidak, ia menggunakan satu atau tempat lain.
Golar Ramblar
20

Jika Anda menginstal JDK, Anda dapat menggunakan jar:

wget -qO- http://example.org/file.zip | jar xvf /dev/stdin
Rory Hunter
sumber
3
Saya baru saja menemukan bahwa jartidak mempertahankan izin file. Trik yang bagus sebaliknya.
phunehehe
7
Anda tidak perlu memberikan param file, cukup gunakan| jar xv
cricket_007
15

Saya tidak berpikir Anda bahkan ingin repot-repot menyalurkan output wget ke unzip.

Dari artikel wikipedia "ZIP (format file)" :

File ZIP diidentifikasi oleh keberadaan direktori pusat yang terletak di akhir file.

wget harus sepenuhnya menyelesaikan unduhan sebelum unzip dapat melakukan pekerjaan apa pun, sehingga mereka berjalan secara berurutan, tidak terjalin seperti yang mungkin dipikirkan orang.

Bruce Ediger
sumber
10

Sintaks yang tepat adalah:

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

tetapi tidak akan berhasil, karena kesalahan ( Info-ZIP di 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.

atau pada BSD / OS X:

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

Ini, karena alat zip standar terutama menggunakan lseekfungsi untuk mengatur offset file di akhir untuk membaca akhir dari catatan direktori pusat . Itu terletak di akhir struktur arsip dan diharuskan membaca daftar file (lihat: Struktur format file zip ). Oleh karena itu file tidak boleh FIFO, pipa, perangkat terminal atau dinamika lainnya, karena objek input tidak dapat diposisikan oleh lseekfungsi.

Jadi, Anda memiliki solusi berikut:

  • menggunakan berbagai jenis kompresi (misalnya tar.gz),
  • Anda harus menggunakan dua perintah terpisah,
  • gunakan alat alternatif (seperti yang disarankan dalam jawaban lain),
  • buat alias atau fungsi untuk menggunakan banyak perintah.
kenorb
sumber
Saya pikir itu masih bisa menjadi FIFO. Anda hanya perlu terus membaca dari FIFO hingga EOF (secara efektif buffering seluruh FIFO dalam memori atau dalam file temp). Benar-benar bisa dilakukan untuk mempermudah pembuatan skrip, tetapi tidak terlalu berguna.
Evan Carroll
8

Repost jawaban saya :

BusyBox's unzipdapat mengambil stdin dan mengekstrak semua file.

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

Tanda hubung unzipadalah menggunakan stdin sebagai input.

Anda bahkan bisa,

cat file.zip | busybox unzip -

Tapi itu hanya mubazir unzip file.zip.

Jika distro Anda menggunakan BusyBox secara default (misalnya Alpine), jalankan saja unzip -.

Saftever
sumber
Trik yang sangat berguna, terima kasih!
Brice
-1

Ini bekerja dengan baik untuk saya:

tar xvf <(curl -sL http://www.vim.org/scripts/download_script.php?src_id=11834)

jar xvf <(curl -sL http://www.vim.org/scripts/download_script.php?src_id=11834)

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

wget -qO- http://www.vim.org/scripts/download_script.php?src_id=11834 | jar xvf -
Maksim Kostromin
sumber