I'm using Amazon Linux and am creating a bash script. I'm tryhing to email an attachment and am having success with

(cat $TFILE1; uuencode $output_file $output_file) | mailx -s "$subject" "$to_email"

However the issue I'm having is taht the attachment is showing up (at least in Gmail) with the name "noname". Is there a way I can make the attachment show up with the same name as the "$output_file" variable?


I've noticed that mail/mailx have issues with attachments. Try using mutt instead, it handles attachments very well and should keep the filename intact.

mutt -a "$attachment_file" -s "$subject" -- "$to_email" < "$TFILE1"

where "$TFILE1" is the body of the mail message. Replace it with /dev/null if all you care to send is the attachment.

  • Hi, Thanks but I have the body of hte email in a file stored in the variable "$TFILE1". How would I incorporate that into what you ahve above? – Dave May 16 '17 at 13:53
  • Hi, I've edited the answer. – dr01 May 16 '17 at 13:58
  • 1
    The cat in backticks is ugly and brittle, and will flatten all whitespace. You want simply <"$TFILE1" there. – tripleee May 16 '17 at 16:00
  • 1
    There are many versions of mailx, some of which support an -a option to attach a file. – tripleee May 16 '17 at 16:04
  • @tripleee Good point, corrected and +1 to your comment. – dr01 May 18 '17 at 8:50

mpack sets the attachment name equal to the input file name. So, for example (-a for attachment instead of inline; -s to set the subject; -c to set the MIME type; 1.png is the file to attach; anthony@localhost is the email address to send to):

mpack -a -s 'test mpack' -c image/png 1.png anthony@localhost

sends me an email with 1.png attached, with a file name:

Content-Type: image/png; name="1.png"
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename="1.png"
Content-MD5: EGqHjkvvXXcaO+41lBN2uA==

So you just need to name your file correctly, then use mpack.

Another option, if you want complete control over the message, is mime-construct.

  • mpack once was fairly ubiquitous, but its last release was in 2003. It's a good utility to have, but you are unlikely to find it installed out of the box many places these days. – tripleee May 17 '17 at 8:40
  • @tripleee indeed, same goes for mime-construct. But OP didn't say it needs to run everywhere, sounds like just on boxes he controls. So he can install it. – derobert May 17 '17 at 18:06
  • I tried "sudo yum install mpack" on my Amazon Linux system but got the error "No package mpack available.". – Dave May 18 '17 at 15:17
  • @Dave you can grab the source from ftp.andrew.cmu.edu/pub/mpack and compile it, or better yet grab the Debian source which has had more recent maintenance: packages.debian.org/source/unstable/mpack rpmfind.net also finds a packaged version, but I can't vouch for it. – derobert May 18 '17 at 15:24
  • Yeah, I"m pretty sure mpack doesn't work with Amazon Linux. When I downloaded teh source, I was able to ./configure, but running make resulted in an "make: *** [unixos.o] Error 1" error. – Dave May 20 '17 at 16:33

uuencode is a remnant from the early 1990s and should be avoided in favor of proper MIME tools if at all possible.

Unfortunately, there is still no de facto standard simple Unix command-line utility for sending MIME messages, though mutt comes close (but it's still primarily an interactive program, and thus includes a fair amount of bloat if all you need is to submit a message to your MTA from a script).

With modern scripting languages, a tool to send a multipart message with an inline text body part with a binary attachment is just a few lines of code. In bare shell script, the code is a bit bulkier; but the real challenge is often to know enough about MIME to be able to pull it off correctly. Briefly, you need to understand the overall structure of a MIME message and how to encode the body part type you want to use.

( printf 'From: %s\nTo: %s\nSubject: %s\n' "$sender" "$recipient" "$subject"
   printf 'Mime-Version: 1.0\nContent-type: multipart/mixed; boundary="foooobar"\n'
   printf '\n--foooobar\n\n'
   cat "$TFILE1"
   printf '\n--foooobar\nContent-type: application/octet-stream; name="%s"\n' "${output_file##*/}"
   printf 'Content-transfer-encoding: base64\n\n'
   base64 "$output_file"
   printf '\n--foooobar--\n' ) |
sendmail -t

This should work for basic 7-bit US-ASCII text; if you need 8-bit text, especially in the headers, there are a number of additional twists (RFC 2047 for human-readable text, RFC 2231 for file names and the like) at which point you'll really want to switch to a language which encapsulates these details so you don't have to understand them or worry about them.

Apart from the dependency on base64 and sendmail for the actual submission, this is pure builtins and very basic shell utilities. The parameter expansion ${output_file##*/} should work with recent shells to remove everything through the final slash, though if you are on a really old one, you might want to use basename instead.

  • Not where I can test this right now - I'll probably update once I get a chance to spot typos etc. Bug reports welcome. – tripleee May 16 '17 at 17:04
  • Updated now. Bug reports still welcome. – tripleee May 17 '17 at 8:35

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.