31

I want to use sendmail to send me stuff and want to do it in a oneliner.

echo "mail content" | sendmail emailataddres.com 

Sends it without subject.

The subject line must come before the Mail content, so I am looking for something along the lines of:

echo "mail content" | prepend "Subject: All that matters" | sendmail emailataddres.com 

sed and awk tend to be really awkward to use and remember.

EDIT:Just to clarify: echo "Mail content" is just an illustrating example. I need to be able to prepend stuff to stdout streams from any source. e.g.: ifconfig, zcat, etc..

AndreasT
  • 729
  • 2
  • 7
  • 16
  • `echo -e "Subject: All that matters\nmail content"`? Or more platform agnostic: `printf 'Subject: %s\n%s\n' "All that matters" "mail content"`. You could also write a small script that just takes the two string arguments to make an even simpler one-liner. – Daniel Andersson Nov 13 '12 at 16:09
  • Well if you add this as an answer I might accept it... :) – AndreasT Nov 13 '12 at 16:18
  • ah, no I don't, sorry. Please regard my edit. – AndreasT Nov 13 '12 at 16:22
  • What should `prepend` do? In order to know how to prepend something, you have to wait until the upstream command (e.g. `echo`) sends the EOF, so that you can insert your data ahead of it in the stream before passing it to stdout to get piped to sendmail. Sounds like a task for a shortish Ruby or Python script. – allquixotic Nov 13 '12 at 16:48
  • I don't have to wait. It can be inserted at the beginning of the stream. – AndreasT Nov 13 '12 at 16:56
  • sed worked great for me. From this [answer](http://stackoverflow.com/a/13884279/878969). `echo "input" | awk '{print "Subject: All that matters"$1}'` – funroll Sep 11 '14 at 17:41
  • 1
    A slightly different approach would be to use the `mail` command (sometimes called bsdmail) instead of `sendmail` directly. `mail` takes an optional `-s subject` option, e.g.: `ifconfig -a | mail -s 'Current ifconfig output' me@someaddr.com` – Wim Lewis Aug 16 '15 at 21:41

5 Answers5

54
$ echo 1 | (echo 2 && cat)
2
1

I am pretty sure that there is a nicer solution, but this should do.

Claudius
  • 8,808
  • 1
  • 15
  • 13
9

Either use what Claudius said or make your own:

~/bin/prepend:

#!/bin/sh
echo -en "$@"
cat -

e.g.:

$ echo "Splendid SUPANINJA! Let's do it!" |\
     prepend "Subject: Venetian Snares\n"

Subject: Venetian Snares
Splendid SUPANINJA! Lets do it!

6

This is inspired by Claudius answer.

If you don't want a break return between your outputs, add the -n param. This will look like:

$ echo 1 | (echo -n 2 && cat)

Which will give:

21

VenomFangs
  • 463
  • 4
  • 16
  • 1
    Actually, no it won't. It gives "2\n1". You have to attach the "-n" to the _second_ echo. Still +1. If you Correct that, I might accept it. I am not sure what's fair, since Claudius contributed the most to the solution. – AndreasT Jul 23 '15 at 14:36
  • Sorry, think I put the `-n` in the wrong place. Anyway, The update should give "21\n" if you want to get rid of the \n then just add a -n before the 1. – VenomFangs Jul 23 '15 at 15:20
2

You can prepend to piped output using process substitution:

$ echo "mail content" | cat <(echo "Subject: All that matters") -
Subject: All that matters
mail content
aparkerlue
  • 206
  • 1
  • 5
1

From the pieces I've gathered... you could do something like this:

echo "Subject: All that matters
`echo "mail content"`" | sendmail blah@blahblah

Notice that I did not close the quotes on the first line... because not all shells translate the \n into a newline character... but I have yet to find one that wont process an actual newline inside the quotes.

When a command is enclosed in the ` character, it will be executed and the output will be injected in-place. Keep in mind that this bit of code is a bit dangerous as it is possible to inject additional commands inline that could easily compromise your system...

****edit**** Following advise of Claudius, a cleaner option would look like this:

echo -e "Subject: All that matters \n $(echo "mail content") |sendmail blah@blahblah

Even with that template, it could be exploited.

TheCompWiz
  • 10,602
  • 1
  • 23
  • 21
  • 1
    It is usually nicer to use `$()` rather than `` as it is supposed to be more portable (and also more readable). Furthermore, you can use `echo`’s `-e` option to make it translate newlines (`echo -e "1\n2"`) or just use printf as suggested by Daniel in the first comment. – Claudius Nov 13 '12 at 16:56
  • Immediately after posting my answer... I read yours & like it better. Good points. – TheCompWiz Nov 13 '12 at 16:58