buat 'file virtual' dari output perintah bash?

36

Saya ingin tahu apakah ada cara untuk membuat 'file virtual' dari keluaran bash.

Contoh: Misalkan saya ingin mengirim email keluaran mysqldumpsebagai lampiran ke alamat email eksternal. Saya dapat menggunakan Mutt untuk melakukannya. The muttpilihan saya perlu digunakan adalah -a <name of the file I want to attach>. Saya tahu saya bisa menggunakan file sementara:

mysqldump mysqldumpoptions > /tmp/tempfile && mutt -a /tmp/tempfile admin@example.org

Tapi saya lebih suka mengarahkan mysqldumpoutput langsung ke Mutt saja. -aOpsi Mutt hanya menerima file dan bukan stream, tapi mungkin ada cara untuk melewatinya semacam deskriptor file virtual atau semacamnya. Sesuatu seperti:

mutt -a $(mysqldump mysqldumpoptions) admin@example.org

Apa itu mungkin? Jika tidak, mengapa?

Ini mungkin contoh yang konyol dan pasti ada cara yang lebih mudah untuk melakukan ini, tapi saya harap ini menjelaskan pertanyaan saya tentang membuat file virtual dari output perintah lain.

Pierre
sumber
1
Saya tidak dapat mulai <() bekerja sampai saya menyadari bahwa saya menggunakan sh bukan bash. Ini bekerja dengan baik. Saya akan mengubah tanggapan yang membantu ketika (jika) saya mencapai reputasi minimum yang diperlukan. Terima kasih atas semua tanggapannya.
Pierre

Jawaban:

53

Ini adalah cara terbersih untuk melakukan apa yang Anda inginkan:

mutt admin@example.org -a <(mysqldump mysqldumpoptions)

The <()operator adalah apa yang Anda minta; itu menciptakan FIFO (atau / dev / fd) dan melakukan fork proses dan menghubungkan stdout ke FIFO. >()melakukan hal yang sama, kecuali menghubungkan stdin ke FIFO sebagai gantinya. Dengan kata lain, itu melakukan semua hal mknod untuk Anda di belakang layar; atau pada OS modern, apakah itu dengan cara yang bahkan lebih baik.

Kecuali, tentu saja, itu tidak bekerja dengan mutt, katanya:

/dev/fd/63: unable to attach file.

Saya menduga masalahnya adalah bahwa mutt sedang mencoba mencari dalam file, yang tidak dapat Anda lakukan pada pipa apa pun. Pencarian mungkin adalah sesuatu seperti memindai file untuk mencari tahu apa tipe MIME itu dan pengkodean apa yang mungkin bekerja (yaitu, apakah file tersebut 7bit atau 8bit), dan kemudian mencari ke awal file untuk benar-benar menyandikannya ke dalam pesan .

Jika yang ingin Anda kirim adalah teks biasa, Anda selalu dapat melakukan sesuatu seperti ini untuk menjadikannya isi utama email (bukan yang ideal, tetapi sebenarnya berfungsi):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org
freiheit
sumber
2
Luar biasa! Saya melihat pengalihan seperti itu untuk pertama kalinya.
Saurabh Barjatiya
Terima kasih atas penjelasannya! Saya belum pernah melihat ini sebelumnya, dalam tutorial tentang I / O redirection.
Christian Mann
4

Saya pikir apa yang Anda cari adalah penggunaan fifo mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Catatan, proses penulisan akan terhambat jika tidak ada proses membaca.

misalnya

mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo
James
sumber
1

Apakah itu perlu lampiran? Jika itu dapat muncul sebagai badan pesan (7-bit clean ascii, tidak mengandung '.' Pada baris dengan sendirinya, dll.), Maka sesuatu seperti ini akan berfungsi:

mysqldump mysqldumpoptions | mutt -s "dump mysql hari ini" [email protected]

pgs
sumber
1

Anda mungkin dapat menggunakan nama file /dev/stdindengan mutt, yang akan dibaca dari stdin-nya.

mysqldump mysqldumpoptions | mutt -a /dev/stdin admin@example.org

Hm, saya baru saja mencoba ini dan mutt mengeluh:

/dev/stdin isn't a regular file.
/dev/stdin: unable to attach file.

Baiklah. Saya pikir ini menjawab pertanyaan Anda, dengan -aopsi mutt mengharapkan file biasa, yang menyiratkan bukan perangkat atau pipa.

Greg Hewgill
sumber
1

FIFO mungkin merupakan cara terbaik. Namun Anda dapat menggunakannya mkfifo /path/to/fifosebagai gantinya

Rory
sumber
0

saya mungkin kehilangan sesuatu di sini, tetapi mengapa menggunakan mutt ketika ini terdengar lebih seperti pekerjaan untuk / usr / sbin / sendmail (atau di mana pun ia tinggal di distro Anda)?

mysqldump mysqldumpoptions | sendmail [email protected]

kebanyakan unix MTA menyediakan perintah / usr / sbin / sendmail, dan mereka semua memahami lebih banyak atau kurang opsi yang sama dan bekerja dengan cara yang kurang lebih sama. dalam hampir semua kasus, Anda tidak perlu peduli MTA / implementasi sendmail mana yang Anda gunakan.

ada beberapa alternatif lain juga, termasuk mail / mailx

cas
sumber
1
maka itu tidak lampiran, yang tampaknya cenderung lebih sulit untuk digunakan untuk penerima
freiheit
1
dalam hal itu, solusi yang lebih baik adalah dengan menggunakan alat seperti metamail (1) atau mime-construct (1p) atau menulis sendiri menggunakan sesuatu seperti modul perl MIME :: Lite (favorit pribadi saya karena membuatnya mudah dilakukan hal-hal yang berhubungan dengan mime yang paling umum).
cas
0

Opsi Mutt -a secara khusus menggunakan tipe MIME yang didefinisikan di /etc/mime.types. Tidak ada tipe file virtual yang menurut Anda adalah tipe mime yang valid terdaftar, jadi saya tidak berpikir lampiran mutt akan berfungsi. Hanya untuk bukti konsep, Anda dapat mencoba menginstal paket dukungan mime (yang menyediakan biner akses file mime seperti lihat, edit, dll) dan jalankan lihat terhadap file virtual (katakanlah sebuah pipa), Anda akan melihat bahwa itu tidak tidak mengenalinya. Masalah mendasar adalah bahwa biasanya file virtual menyimpan konten data dalam memori, bukan pada disk, objek file hanyalah sebuah pointer. Anda bahkan dapat mencoba membungkus file virtual dengan tar / gz dan membuat mutt senang tapi saya ragu Anda akan mendapatkan sesuatu yang berguna dari ujung yang lain ... :)


sumber