How do I Send Email from the Command Line? - linux

I would like to quickly send email from the command line. I realize there are probably a number of different ways to do this.
I'm looking for a simple way to do this from a linux terminal (likely a bash shell but anything should do) and an alternative way to do this on Windows. I want to be able to whip up an email right on the command line or have the flexibility to pipe the message into the command line program. How would you go about doing this? If you have small scripts that would be fine as well.

$ echo "This is the email body" | mail -s "This is the subject" me#email.com
Alternatively:
$ cat | mail -s "A few lines off the top of my head" me#here.com
This is where my
multiline
message would go
^D
^D - means press ctrl+d

You can use mail:
$mail -s <subject> <recipients>
You then type your message and end it with a line that has only a period. This signals you are done and sends the message.
You can also pipe your email in from STDIN and it will be sent as the text of an email:
$<mail-generating-program> | mail -s <subject> <recipients>
One small note with this approach - unless your computer is connected to the internet and your DNS settings are set properly, you won't be able to receive replies to your message. For a more robust command-line program you can link to your POP or IMAP email account, check out either pine or mutt.

You can also use this sendmail version for windows. It is very simple to use, standard UNIX-like behavior. Fast. Does not need any installation, just call the EXE wherever it is located on your system.
Composing the email:
echo To: you#example.com, me#example.com >> the.mail
echo From: them#example.com >> the.mail
echo Subject: This is a SENDMAIL notification >> the.mail
echo Hello World! >> the.mail
echo This is simple enough. >> the.mail
echo .>> the.mail
Sending the file:
\usr\lib\sendmail.exe -t < the.mail
type the.mail | C:\Projects\Tools\sendmail.exe -t

If you are looking to do this from a Windows command line, there is a tool called blat that can be used from a CMD prompt.
It is a bit more fun from PowerShell. Since PowerShell has access to the .NET Framework, you can use the classes from System.Net.Mail to send email. There is an example script on the PowerShell Community Script Repository.

IIRC you'll also have to configure a mail transfer agent (MTA) to use mail or most email libraries. Sendmail is the most well known but is a real pig when it comes to configuration. Exim, Qmail and Postfix are all popular alternatives that are a bit more modern.
There are also more lightweight MTAs that are only able to send out mail, not receive it: nullmailer, mstmp, ssmtp, etc.
Postfix is default for Ubuntu. This wiki article describes how to configure it - be sure to only allow forwarding from your local address!

Here is a Power Shell example of a script to send email:
$smtp = new-object Net.Mail.SmtpClient("mail.example.com")
if( $Env:SmtpUseCredentials -eq "true" ) {
$credentials = new-object Net.NetworkCredential("username","password")
$smtp.Credentials = $credentials
}
$objMailMessage = New-Object System.Net.Mail.MailMessage
$objMailMessage.From = "script#mycompany.com"
$objMailMessage.To.Add("you#yourcompany.com")
$objMailMessage.Subject = "eMail subject Notification"
$objMailMessage.Body = "Hello world!"
$smtp.send($objMailMessage)

If you want to invoke an email program, then see this article:
How do I open the default mail program with a Subject and Body in a cross-platform way?

If you are on a Linux server, but mail isn't available (which can be the case on shared servers), you can write a simple PHP / Perl / Ruby (depending on what's available) script to do the same thing, e.g. something like this:
#! /usr/bin/php
<?php
if ($argc < 3) {
echo "Usage: " . basename($argv[0]) . " TO SUBJECT [CC]\n";
exit(1);
}
$message = file_get_contents('php://stdin', 'r');
$headers = $argc >= 4 ? "Cc: $argv[3]\r\n" : null;
$ret = mail($argv[1], $argv[2], $message, $headers);
exit($ret ? 0 : 1);
Then invoke as follows:
mail me#example.com test < message

Related

Shell script to send a custom message to users listed in a file?

I would like to write a shell script, that opens two text files (e.g message.txt, users.txt) and sends the message found in the first file ($1) to every single user found in the second file ($2)?
If a user is currently logged in, the message should be sent with the "write" command, else (if they are not currently logged in), it will be sent as a "mail".
I tried running this code:
#!/bin/bash
msg=`cat $1`
input=$2
while IFS= read -r usr
do
`write $usr $msg`
if [ $? -eq 1 ]
#here I tried checking if the $usr found in the $2 file is not online
`mail $usr $msg`
#The Subject part could also be a problem here
fi
done < "$input"
However, I am unsure how the mail part should be done, when running the code it even says that there is an error on line 22 (where I tried mailing the user).
You can use the following syntax to send an email via bash:
mail -s 'message subject' username#gmail.com <<< 'testing message body'
So in your case, you should add the -s parameter before the subject and you should add the body to add to your email. (you can use '' for empty body)
Another syntax to perform that:
echo "text message body" | mail -s "message subject" username#gmail.com
PS: You should not use the backticks (``) for the mail command

Change the From field in an email with the mail command under linux without the -a option

Problem: when I use the mail command under linux (Ubuntu Server 16.04) as root to send an email (several scripts on my server do so), the From: field in the mail header looks like From: root#mydomain.org. I want it to look like From: admin#mydomain.org.
Attempt: I already found the option -a "From: admin#mydomain.org" to add the field to the mail header.
My whole command looks like this:
echo "content" | mail -s "subject" "recipient#wherever.org" -a "From: admin#mydmain.org"
Second Problem: However, I do not want to write the -a option at every point I use the mail command in a script because this is some kind of hard coding.
Second Attempt: My best attempt yet is to write a wrapper, though I think there should be a cleaner method to always add that header field to mails sent with the mail command.
Question: Does anyone know a better way which does not include hard coding? Still I want to use such a simple command line as above to not make things unnecessary complicated.
Best
Fabian
the mail command reads ~/.mailrc or a different startup file given by the environment variable MAILRC. (see manpage, http://manpages.ubuntu.com/manpages/xenial/man1/bsd-mailx.1.html#contenttoc4)
this file can contain the line set from=you#example.org.
conf="$(mktemp)"
trap 'rm -f "$conf"' EXIT
echo set from=you#example.org > "$conf"
export MAILRC="$conf"
# now mail will use you#example.org as From:

In Unix, how to display welcome message if user has logged in from a particular IP (or host)?

I want to display one message if user XYZ has logged in from any IP (or host).
Check to see if you have environment variables such as SSH_CLIENT and SSH_CONNECTION set. If so, you can access these from scripts (perl, bash, etc...) to dynamically generate a welcome message. Below, is a simple perl script to extract the IP address from env var SSH_CLIENT and output a welcome message.
#!/usr/bin/env perl
use strict; use warnings;
my $ip = (split / /, $ENV{SSH_CLIENT})[0];
if ($ip eq 'xxx.xxx.xxx.xxx') {
print "Hello XXXX\n";
}
else {
print "Hello from unknown IP\n";
}
Then you need to execute this script at login time. You can do this by calling the script from the end of /etc/profile.
Also This can be done using shell script as
REMOTE_IP=`echo $SSH_CONNECTION | cut -f1 -d " "`
if [ $REMOTE_IP == 'XXX.XXX.XXX.X' ] ;
then echo "Hi XXX" ;
else echo "Hi, stranger...";
fi
And then run this script from /etc/profile

Bash mail - Send as another user only

I've been working on sending HTML emails using BSD mail and so far I've been successful. I've even been able to modify, not change though, the sender.
Current Command:
cat $htmlFile | mail -s "$(echo -e "$subject\nContent-Type: text/html")" $recipient -v -- -F $sender
However when the email comes through, the sender is only appending the $sender to the host name. Let's assume that the following is true
$user=root
$HOSTNAME=server.com
$sender='Application Support<support#acmeinc.com>'
When the email comes through it reads:
Application Support<support#acmeinc.com> <root#server.com>
How can I make it so that only the $sender variable is used in the email instead of appended?
OS: RHEL 5.10
Kernel Rev: 2.6.18-371.8.1.el5
Still not sure what you're trying to do here, so I will take a stab and guess that you are looking for the -r flag? It sets the 'from-addr'. I don't think it is present/supported in BSD mail, but it is in mailx.
Other options include doing stuff with postfix/sendmail in order to set the sender address. You can do lots of stuff with aliases and the like, and more advanced mangling can be done through "transports" if you write your own handler.

How to attach a file using mail command on Linux? [duplicate]

This question already has answers here:
How do I send a file as an email attachment using Linux command line?
(25 answers)
Closed 5 years ago.
I'm on a server running a Linux shell.
I need to mail a simple file to a recipient.
How to do this, prefereably using only the mail command?
UPDATE: got a good solution, using mutt instead:
$ echo | mutt -a syslogs.tar.gz admin#domain.org
Example using uuencode:
uuencode surfing.jpeg surfing.jpeg | mail sylvia#home.com
and reference article:
http://www.shelldorado.com/articles/mailattachments.html
Note:
you may apt install sharutils to have uuencode command
mail on every version of modern Linux that I've tried can do it. No need for other software:
matiu#matiu-laptop:~$ mail -a doc.jpg someone#somewhere.com
Subject: testing
This is a test
EOT
ctrl+d when you're done typing.
$ echo | mutt -a syslogs.tar.gz admin#domain.org
But it uses mutt, not mail (or mailx).
mailx might help as well. From the mailx man page:
-a file
Attach the given file to the message.
Pretty easy, right?
My answer needs base64 in addition to mail, but some uuencode versions can also do base64 with -m, or you can forget about mime and use the plain uuencode output...
FROM=me#mydomain.com
TO=someone#mydomain.com
SUBJECT="Auto emailed"
MIME="application/x-gzip" # Adjust this to the proper mime-type of file
FILE=somefile.tar.gz
ENCODING=base64
boundary="---my-unlikely-text-for-mime-boundary---$$--"
(cat <<EOF
From: $FROM
To: $REPORT_DEST
Subject: $SUBJECT
Date: $(date +"%a, %b %e %Y %T %z")
Mime-Version: 1.0
Content-Type: multipart/mixed; boundary="$boundary"
Content-Disposition: inline
--$boundary
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
This email has attached the file
--$boundary
Content-Type: $MIME;name="$FILE"
Content-Disposition: attachment;filename="$FILE"
Content-Transfer-Encoding: $ENCODING
EOF
base64 $FILE
echo ""
echo "--$boundary" ) | mail
mailx -a /path/to/file email#address
You might go into interactive mode (it will prompt you with "Subject: " and then a blank line), enter a subject, then enter a body and hit Ctrl+D (EOT) to finish.
mpack -a \
-s"Hey: might this serve as your report?" \
-m 0 -c application/x-tar-gz \
survey_results.tar.gz \
hesco#example.net
mpack and munpack work together with metamail to extend mailx
and make it useful with modern email cluttered with HTML markup and attachments.
Those four packages taken together will permit you to handle
any email you could in a GUI mail client.
Using ubuntu 10.4, this is how the mutt solution is written
echo | mutt -a myfile.zip -- admin#domain.org
There are a lot of answers here using mutt or mailx or people saying mail doesn't support "-a"
First, Ubuntu 14.0.4 mail from mailutils supports this:
mail -A filename -s "subject" email#example.com
Second, I found that by using the "man mail" command and searching for "attach"
The following is a decent solution across Unix/Linux installations, that does not rely on any unusual program features. This supports a multi-line message body, multiple attachments, and all the other typical features of mailx.
Unfortunately, it does not fit on a single line.
#!/bin/ksh
# Get the date stamp for temporary files
DT_STAMP=`date +'%C%y%m%d%H%M%S'`
# Create a multi-line body
echo "here you put the message body
which can be split across multiple lines!
woohoo!
" > body-${DT_STAMP}.mail
# Add several attachments
uuencode File1.pdf File1.pdf > attachments-${DT_STAMP}.mail
uuencode File2.pdf File2.pdf >> attachments-${DT_STAMP}.mail
# Put everything together and send it off!
cat body-${DT_STAMP}.mail attachments-${DT_STAMP}.mail > out-${DT_STAMP}.mail
mailx -s "here you put the message subject" nobody#test-address.com < out-${DT_STAMP}.mail
# Clean up temporary files
rm body-${DT_STAMP}.mail
rm attachments-${DT_STAMP}.mail
rm out-${DT_STAMP}.mail
On Linux I would suggest,
# FILE_TO_BE_ATTACHED=abc.gz
uuencode abc.gz abc.gz > abc.gz.enc # This is optional, but good to have
# to prevent binary file corruption.
# also it make sure to get original
# file on other system, w/o worry of endianness
# Sending Mail, multiple attachments, and multiple receivers.
echo "Body Part of Mail" | mailx -s "Subject Line" -a attachment1 -a abc.gz.enc "youremail#domain.com anotheremail#domain.com"
Upon receiving mail attachment, if you have used uuencode, you would need uudecode
uudecode abc.gz.enc
# This will generate file as original with name as same as the 2nd argument for uuencode.
I use mailutils and the confusing part is that in order to attach a file you need to use the capital A parameter. below is an example.
echo 'here you put the message body' | mail -A syslogs.tar.gz admin#domain.org
If you want to know if your mail command is from mailutils just run "mail -V".
root#your-server:~$ mail -V
mail (GNU Mailutils) 2.99.98
Copyright (C) 2010 Free Software Foundation, inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
With mailx you can do:
mailx -s "My Subject" -a ./mail_att.csv -S from=noreply#foo.com recipient#bar.com < ./mail_body.txt
This worked great on our GNU Linux servers, but unfortunately my dev environment is Mac OsX which only has a crummy old BSD version of mailx. Normally I use Coreutils to get better versions of unix commands than the Mac BSD ones, but mailx is not in Coreutils.
I found a solution from notpeter in an unrelated thread (https://serverfault.com/questions/196001/using-unix-mail-mailx-with-a-modern-mail-server-imap-instead-of-mbox-files) which was to download the Heirloom mailx OSX binary package from http://www.tramm.li/iWiki/HeirloomNotes.html.
It has a more featured mailx which can handle the above command syntax.
(Apologies for poor cross linking linking or attribution, I'm new to the site.)

Resources