pengembangan-web-mp-pd.com

Membuka ritsleting file yang terbang melalui pipa

Bisakah saya membuat unzip atau program serupa bekerja pada output standar? Situasinya adalah saya mengunduh file Zip, yang seharusnya dibuka ritsleting dengan cepat.

Masalah terkait: Bagaimana cara menyalurkan file yang diunduh ke output standar dalam bash?

43
Alex

Walaupun file Zip sebenarnya merupakan format kontainer, tidak ada alasan mengapa itu tidak dapat dibaca dari sebuah pipa (stdin) jika file tersebut dapat masuk ke dalam memori dengan cukup mudah. Berikut ini adalah skrip Python yang mengambil file Zip sebagai input standar dan mengekstraksi konten ke direktori saat ini atau ke direktori yang ditentukan jika ditentukan.

import zipfile
import sys
import StringIO
data = StringIO.StringIO(sys.stdin.read())
z = zipfile.ZipFile(data)
dest = sys.argv[1] if len(sys.argv) == 2 else '.'
z.extractall(dest)

Script ini dapat diperkecil menjadi satu baris dan dibuat sebagai alias.

alias unzip-stdin="python -c \"import zipfile,sys,StringIO;zipfile.ZipFile(StringIO.StringIO(sys.stdin.read())).extractall(sys.argv[1] if len(sys.argv) == 2 else '.')\""

Sekarang unzip output wget dengan mudah.

wget http://your.domain.com/your/file.Zip -O - | unzip-stdin target_dir
22
Jason R. Coombs

Ini tidak mungkin berhasil seperti yang Anda harapkan. Zip bukan hanya format kompresi, tetapi juga format wadah. Ini menggulung pekerjaan tar dan gzip.bzip2 menjadi satu. Karena itu, jika Zip Anda memiliki satu file, Anda dapat menggunakan unzip -p untuk mengekstrak file ke stdout. Jika Anda memiliki lebih dari satu file, tidak ada cara bagi Anda untuk mengetahui di mana mereka mulai dan berhenti.

Sedangkan untuk membaca dari stdin, halaman manual unzip memiliki kalimat ini:

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

Anda mungkin beruntung dengan funzip.

18
David Pashley

Apa yang ingin Anda lakukan adalah, membuat unzip mengambil file ZIPped pada input standar bukan sebagai argumen. Ini biasanya mudah didukung oleh gzip dan tar jenis alat dengan - argumen. Tetapi standar unzip tidak melakukan itu (meskipun, itu mendukung ekstraksi ke pipa). Namun, semuanya tidak hilang ...

Lihatlah funzip halaman manual.

funzip tanpa argumen file bertindak sebagai filter; yaitu, diasumsikan bahwa arsip Zip (atau file gzip'd) sedang disalurkan ke input standar, dan mengekstrak anggota pertama dari arsip ke stdout. Ketika stdin berasal dari perangkat tty, funzip mengasumsikan bahwa ini bukan aliran data terkompresi (biner) dan menampilkan teks bantuan singkat. Jika ada argumen file, maka input dibaca dari file yang ditentukan dan bukan dari stdin.

Mengingat keterbatasan pada ekstraksi anggota tunggal, funzip paling berguna dalam hubungannya dengan program pengarsipan sekunder seperti tar (1). Bagian berikut termasuk contoh yang menggambarkan penggunaan ini dalam hal cadangan disk untuk direkam.

Ini berjalan baik dengan gagasan bahwa kebanyakan arsip linux biasanya TAR'ed dan kemudian ZIP dalam beberapa cara (gzip, bzip, et al). Ini akan bekerja untuk Anda jika Anda memiliki tar.Zip.


Perlu dicatat bahwa funzip ditulis oleh penulis asli Info-Zip Mark Adler. Dia menulis di halaman manual funzip,

this functionality should be incorporated into unzip itself (future release).

namun, tidak ada pembaruan seperti itu terlihat di sekitar. Saya menduga bahwa Markus merasa tidak perlu karena metode pengarsipan lainnya bekerja dengan mudah dengan TAR.

7
nik

Saya suka menggunakan curl karena diinstal secara default (-L Diperlukan untuk pengalihan yang sering terjadi):

curl -L http://example.com/file.Zip | bsdtar -xvf - -C /path/to/directory/

Namun, bsdtar tidak diinstal secara default, dan saya tidak bisa membuat funzip berfungsi.

7
Todd Partridge

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 untuk 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 dekompresor Zip gagal ketika arsip dipasok melalui pipa.

Direktori di akhir arsip bukan hanya lokasi tempat informasi meta file disimpan dalam arsip. Selain itu, setiap entri juga menyertakan informasi ini dalam 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 menjadi libarchive (alias bsdtar dan bsdcpio) dapat dan akan melakukannya ketika membaca melalui pipa, artinya hal berikut mungkin terjadi:

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

Di zsh, Anda dapat melakukan hal berikut:

unzip =( curl http://example.com/someZipFile.Zip )
4
Ian Robertson

Utilitas umum paling sederhana yang tersedia yang akan melakukan ini adalah jar, yang akan menganggap STDIN sedang digunakan jika Anda tidak memberikan file args. Itu juga membutuhkan argumen yang mirip dengan program tar untuk operasi.

misalnya daftar isi arsip

curl https://my.example.com/file.Zip | jar t

Walaupun Java tidak selalu terinstal, pada mesin-mesin di mana ia berada, jar jelas merupakan metode yang paling mudah untuk melakukan ini.

4
Adrian

Tidak mungkin dengan Info-Zip yang merupakan implementasi OSS paling umum. Lebih penting lagi, itu tidak direkomendasikan karena konstruksi arsip Zip.

Jika perubahan format dapat dilakukan untuk Anda, maka pertimbangkan untuk menggunakan tar (1). Cukup senang dengan input/output yang dialirkan dan, pada kenyataannya, mengharapkannya secara default.

Selain itu, Anda sering dapat mengetahui apakah aplikasi mengharapkan input/output yang dialirkan dengan menentukan "-" untuk nama file. Info-Zip, seperti yang dapat Anda bayangkan, tidak memperlakukan ini sebagai argumen yang valid.

4
Dan Carley

Repost jawaban saya :

BusyBox unzip dapat mengambil stdin dan mengekstrak semua file.

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

Tanda hubung setelah unzip adalah 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 (mis. Alpine), jalankan unzip -.

3
Saftever

Saya benar-benar membutuhkan sesuatu yang sedikit lebih kompleks - mengekstrak file tertentu jika ada. Kesulitannya, aliran file input mungkin bukan file Zip, dan dalam hal ini, saya membutuhkannya untuk melanjutkan melalui pipa. Inilah solusi saya (sebagian besar berkat solusi Jason R. Coombs)

python -c "import zipfile,sys,StringIO
data=sys.stdin.read()
try:
    z=zipfile.ZipFile(StringIO.StringIO(data))
    z.open(\"$1\")
    sys.stdout.write(z.read(\"$1\"))
except (RuntimeError, zipfile.BadZipfile):
    sys.stdout.write(data)"

Saya menyimpan ini sebagai file bernama "effpoptp" (bukan nama sederhana) di folder "/ bin" di komputer saya jadi mengujinya seperti ini:

cat defaultModel.mwb|effpoptp "document.mwb.xml"

Tujuannya adalah untuk mengontrol file MySQL Workbench versi, di mana file tersebut bisa menjadi file xml bernama sebagai file workbench, atau file workbench lengkap.

1
SEoF