I wonder if there is a way to create a 'virtual file' from a bash output.

Example: Let's say I want to email the output of mysqldump as an attachment to an external email address. I can use Mutt to do so. The mutt option I need to use is -a <name of the file I want to attach>. I know I could use a temporary file:

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

But I would rather redirect the mysqldump output directly to Mutt instead. Mutt's -a option only accepts a file and not a stream, but maybe there is a way to pass it some kind of virtual file descriptor or something along those lines. Something like:

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

Is it possible? If not, why?

This is maybe a silly example and there surely are easier ways to do this, but I hope it explains my question about creating a virtual file from the output of another command.

  • 1
    I couldn't get <() to work until I realized I was using sh instead of bash. It is working great. I will upvote the helpful responses when (if) I reach the minimum needed reputation. Thank you for all the responses.
    – ppbitb
    Jul 14 '09 at 17:05

This is the cleanest way to do what you want:

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

The <() operator is what you were asking for; it creates a FIFO (or /dev/fd) and forks a process and connects stdout to the FIFO. >() does the same, except connects stdin to the FIFO instead. In other words, it does all the mknod stuff for you behind the scenes; or on a modern OS, does it in an even better way.

Except, of course, that doesn't work with mutt, it says:

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

I suspect the problem is that mutt is trying to seek in the file, which you can't do on a pipe of any sort. The seeking is probably something like scanning the file to figure out what MIME type it is and what encodings might work (ie, whether the file is 7bit or 8bit), and then seeking to the beginning of the file to actually encode it into the message.

If what you want to send is plain text, you could always do something like this to make it the main contents of the email instead (not ideal, but it actually works):

mysqldump mysqldumpoptions | mutt -s "Here's that mysqldump" admin@example.org

I think what you are looking for is a fifo using mknod

mknod /tmp/foo p

echo hello > /tmp/foo &

cat /tmp/foo

Note, the writing process will block if there is no reading process.


mknod /tmp/foo p

mysqldump mysqldumpoptions > /tmp/foo &

mutt -a /tmp/foo

A FIFO is probably the best way. However you can use mkfifo /path/to/fifo instead


Does it need to be an attachment? If it can appear as the body of a message (7-bit clean ascii, doesn't contain '.' on a line by itself, etc.), then something like this would work:

mysqldump mysqldumpoptions | mutt -s "today's mysql dump" admin@example.org


You may be able to use the filename /dev/stdin with mutt, which will read from its stdin.

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

Hm, I just tried this and mutt complains:

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

Oh well. I think this answers your question though, with the -a option mutt expects a regular file, which implies not a device or pipe.


i may be missing something here, but why use mutt when this sounds more like a job for /usr/sbin/sendmail (or wherever it lives on your distro)?

mysqldump mysqldumpoptions | sendmail admin@example.org

most unix MTAs provide a /usr/sbin/sendmail command, and they all understand more-or-less the same options and work in more-or-less the same way. in almost all cases, you don't need to care which particular MTA/implementation of sendmail you're using.

there are several other alternatives too, including mail/mailx

  • 1
    then it's not an attachment, which seems likely to be harder to use for the recipient
    – freiheit
    Jul 14 '09 at 7:06
  • 1
    in that case, a better solution would be to use a tool like metamail(1) or mime-construct(1p) or writing your own using something like the perl MIME::Lite module (my personal favourite because it makes it easy to do the most common mime-related things).
    – cas
    Jul 14 '09 at 9:49

Mutt -a option specifically uses MIME types defined at /etc/mime.types. None of the virtual file types that you would think are actually a valid mime type registered, so I don't think mutt attachment would work. Just for the proof of the concept, you can try install mime-support package (which provides mime file access binaries such as see, edit, etc) and run see against a virtual file (say a pipe), you will see that it does not recognize it. The fundamental issue is that normally a virtual file holds data content in memory, not on disk, the file object is just a pointer. You can even try wrap a virtual file with tar/gz and make mutt happy but I doubt you will get anything useful out of the other end... :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.