Saya memiliki proses paralel yang memalukan yang menciptakan sejumlah besar file yang identik (tetapi tidak sepenuhnya). Apakah ada cara untuk mengarsipkan file "on the fly", sehingga data tidak mengkonsumsi lebih banyak ruang daripada yang diperlukan?
Proses itu sendiri menerima parameter baris perintah dan mencetak nama setiap file yang dibuat untuk stdout. Saya memintanya untuk parallel --gnu
mengurus distribusi input (yang berasal dari proses lain) dan mengumpulkan output:
arg_generating_process | parallel --gnu my_process | magic_otf_compressor
CONTOH SEDERHANA untuk bagian pertama pipa di bash
:
for ((f = 0; $f < 100000; f++)); do touch $f; echo $f; done
Bagaimana bisa magic_otf_compressor
terlihat seperti? Seharusnya memperlakukan setiap baris input sebagai nama file, menyalin setiap file ke .tar
arsip terkompresi (arsip yang sama untuk semua file yang diproses!) Dan kemudian menghapusnya. (Sebenarnya, itu sudah cukup untuk mencetak nama setiap file yang diproses, yang lain | parallel --gnu rm
bisa menghapus file-file tersebut.)
Apakah ada alat seperti itu? Saya tidak mempertimbangkan mengompresi setiap file secara terpisah, ini akan menghabiskan terlalu banyak ruang. Saya telah melihat ke dalam archivemount
(akan membuat sistem file dalam memori -> tidak mungkin, file saya terlalu besar dan terlalu banyak) dan avfs
(tidak bisa membuatnya bekerja bersama dengan FUSE). Apa yang saya lewatkan?
Saya sendiri hanya selangkah lagi dari meretas alat semacam itu, tetapi seseorang pasti pernah melakukannya sebelumnya ...
EDIT : Pada dasarnya saya pikir saya sedang mencari front-end stdin untuk libtar
(sebagai lawan dari front-end command-line tar
yang membaca argumen dari, well, baris perintah).
sumber
Jawaban:
Sepertinya
tar
ingin tahu semua nama file dimuka. Jadi lebih sedikit on-the-fly dan lebih banyak after-the-fly.cpio
tampaknya tidak memiliki masalah itu:sumber
tar
dalam kode untuk melihat bahwa ada fungsi yang mengembalikan nama file berikutnya untuk diproses, yang membuat saya membaca dokumentasi lagi. - Jadi,stdout
diarahkan kegzip
proses melalui proses substitusi, danstderr
dialihkan kestdout
yang diproses oleh langkah selanjutnya dalam pipa?tar
membaca daftar file terlebih dahulu, menggunakan contoh sederhana yang saya tambahkan ke pertanyaan saya. Namun, membacatar
kode sumber lagi, menurut saya harus membaca daftar file "on the fly" jika tidak membuat arsip tambahan. Sayangnya, saya mengalami kesalahan saat mengkompilasitar
dari sumber ... :-(cpio
, selaingrep -v 'blocks$'
. (head -n -1
menggunakan buffer yang sangat besar ...) Membuat solusi ini sedikit meretas, tetapi tidak apa-apa ;-)head -n -1
hanya menggunakan 16MB saat dijalankan pada beberapa GB data. Anda selalu dapat menggunakan perl: perl -ne 'print $ last; $ last = $ _'Kasus klasik RTFM (semuanya!) . The
-T
pilihan untuk GNUtar
akan membaca file yang akan diarsipkan dari file lain (dalam kasus saya,/dev/stdin
, Anda juga dapat menggunakan-
), dan bahkan ada--remove-files
pilihan:(menggunakan versi paralel
xz
untuk kompresi, tetapi Anda dapat menggunakan kompresor pilihan Anda sebagai gantinya). Untuk digunakan sebagai:EDIT : Seperti yang ditunjukkan Ole,
tar
sepertinya membaca seluruh daftar file dengan-T
opsi untuk beberapa alasan. Tes berikut mengkonfirmasi hal ini:Ada penundaan satu detik di sistem saya sebelum semua file dicetak sekaligus; sebaliknya, jika
tar
perintah digantikan olehcat
, semua file dicetak saat dibuat. Saya telah mengajukan permintaan dukungan kepada orang-orang tar, mari kita lihat.EDIT ^ 2 :
tar
Perbaikan terbaru dari sumber ini. Ini belum ada di Ubuntu 13.10, tetapi mungkin disertakan dengan 14.04.sumber
Entah bagaimana ini tampaknya bukan pekerjaan yang baik untuk kompresor padat (pengarsipan + kompresi berbasis tape). Memasukkan file satu per satu terlihat seperti pekerjaan untuk
zip
atau format lain yang memungkinkan akses file acak dalam arsip dan penyisipan tambahan.Fakta bahwa file-file tersebut serupa tidak akan banyak membantu dalam kedua kasus tersebut. Dalam
zip
, file dikompresi secara terpisah, dan dalam kompresor padat, biasanya ada jendela di mana kompresi berlangsung.Jika file berbasis teks, Anda dapat menyimpan diff dibandingkan dengan file referensi tunggal. Untuk biner, ini sedikit lebih rumit tetapi bisa dilakukan.
Ada juga cara formal (bukan hanya menulis, tetapi filesystem yang tepat). Sebagai contoh, sistem file ZFS dan BTRFS menawarkan kompresi transparan. Anda juga dapat menggunakan http://developer.berlios.de/projects/fusecompress ini
sumber
xz
tampaknya beroperasi dengan ukuran kamus default 8M (pada tingkat kompresi standar-6
), yang tampaknya cukup untuk kasus penggunaan saya. - Diff ke file referensi memang bagus, tetapi harus membuat file referensi terlebih dahulu. Apakah sistem file kompresi mendeteksi file dengan konten yang hampir identik?btrfs
memiliki copy-on-write, jadi jika Anda menyalin file dan memodifikasi bagian dari itu, itu hanya menyimpan bagian yang Anda ubah. Jika Anda tidak membuat file dengan cara ini, seharusnya ada alat deduplikasi , tetapibtrfs
belum menjadi sistem file yang matang dan stabil dan deduplikasi ini masih dalam tahap pengembangan awal. Tetapi sekarang saya memikirkannya, bagaimana dengan lessfs.com/wordpressIni mungkin tidak tampak jelas, tetapi saya bertaruh
squashfs
akan sempurna untuk ini - dan itu bahkan diimplementasikan dalam kernel. Karena versi 4.1squashfs
dapat menangani file pseudo seperti yang ditentukan padamksquash
baris perintah atau melalui skrip shell danmksquashfs
akan menghasilkan file saat membuat arsip.Ia dapat menangani pipa - misalnya, Anda dapat menangkap proses lain
stdout
ke dalam arsip squash yang dapat dipasang - bahkan fifos - sangat keren. Dalam kasus Anda, jika Anda bisa bekerja di luar logistik naskah pipa output proses Anda melalui itu, Anda bisa membungkus proses Anda sepenuhnya dimksquashfs
dan angin dengan arsip tunggal. Ini sedikit darireadme
cara kerjanya dan masih ada lagi di sini :sumber
test
dan filefile
di direktori ini. Bisakah Anda memberikan contoh singkat?