Monday, December 5, 2011

exim cheat sheet

I just need to document this great resource which always helps me deal with exim basics ... I fear one day it won't be there : )

taken from:

Exim Cheatsheet

Here are some useful things to know for managing an Exim 4 server. This assumes a prior working knowledge of SMTP, MTAs, and a UNIX shell prompt.

Message-IDs and spool files

The message-IDs that Exim uses to refer to messages in its queue are mixed-case alpha-numeric, and take the form of: XXXXXX-YYYYYY-ZZ. Most commands related to managing the queue and logging use these message-ids.

There are three -- count 'em, THREE -- files for each message in the spool directory. If you're dealing with these files by hand, instead of using the appropriate exim commands as detailed below, make sure you get them all, and don't leave Exim with remnants of messages in the queue. I used to mess directly with these files when I first started running Exim machines, but thanks to the utilities described below, I haven't needed to do that in many months.

Files in /var/spool/exim/msglog contain logging information for each message and are named the same as the message-id.

Files in /var/spool/exim/input are named after the message-id, plus a suffix denoting whether it is the envelope header (-H) or message data (-D).

These directories may contain further hashed subdirectories to deal with larger mail queues, so don't expect everything to always appear directly in the top /var/spool/exim/input or /var/spool/exim/msglog directories; any searches or greps will need to be recursive. See if there is a proper way to do what you're doing before working directly on the spool files.

Basic information

Print a count of the messages in the queue:

root@localhost# exim -bpc 

Print a listing of the messages in the queue (time queued, size, message-id, sender, recipient):

root@localhost# exim -bp 

Print a summary of messages in the queue (count, volume, oldest, newest, domain, and totals):

root@localhost# exim -bp | exiqsumm 

Print what Exim is doing right now:

root@localhost# exiwhat 

Test how exim will route a given address:

root@localhost# exim -bt     <--   router = localuser, transport = local_delivery root@localhost# exim -bt   router = localuser, transport = local_delivery root@localhost# exim -bt   router = lookuphost, transport = remote_smtp   host [] MX=0 

Run a pretend SMTP transaction from the command line, as if it were coming from the given IP address. This will display Exim's checks, ACLs, and filters as they are applied. The message will NOT actually be delivered.

root@localhost# exim -bh 

Display all of Exim's configuration settings:

root@localhost# exim -bP 

Searching the queue with exiqgrep

Exim includes a utility that is quite nice for grepping through the queue, called exiqgrep. Learn it. Know it. Live it. If you're not using this, and if you're not familiar with the various flags it uses, you're probably doing things the hard way, like piping `exim -bp` into awk, grep, cut, or `wc -l`. Don't make life harder than it already is.

First, various flags that control what messages are matched. These can be combined to come up with a very particular search.

Use -f to search the queue for messages from a specific sender:

root@localhost# exiqgrep -f [luser]@domain 

Use -r to search the queue for messages for a specific recipient/domain:

root@localhost# exiqgrep -r [luser]@domain 

Use -o to print messages older than the specified number of seconds. For example, messages older than 1 day:

root@localhost# exiqgrep -o 86400 [...] 

Use -y to print messages that are younger than the specified number of seconds. For example, messages less than an hour old:

root@localhost# exiqgrep -y 3600 [...] 

Use -s to match the size of a message with a regex. For example, 700-799 bytes:

root@localhost# exiqgrep -s '^7..$' [...] 

Use -z to match only frozen messages, or -x to match only unfrozen messages.

There are also a few flags that control the display of the output.

Use -i to print just the message-id as a result of one of the above two searches:

root@localhost# exiqgrep -i [ -r | -f ] ... 

Use -c to print a count of messages matching one of the above searches:

root@localhost# exiqgrep -c ... 

Print just the message-id of the entire queue:

root@localhost# exiqgrep -i 

Managing the queue

The main exim binary (/usr/sbin/exim) is used with various flags to make things happen to messages in the queue. Most of these require one or more message-IDs to be specified in the command line, which is where `exiqgrep -i` as described above really comes in handy.

Start a queue run:

root@localhost# exim -q -v 

Start a queue run for just local deliveries:

root@localhost# exim -ql -v 

Remove a message from the queue:

root@localhost# exim -Mrm  [  ... ] 

Freeze a message:

root@localhost# exim -Mf  [  ... ] 

Thaw a message:

root@localhost# exim -Mt  [  ... ] 

Deliver a message, whether it's frozen or not, whether the retry time has been reached or not:

root@localhost# exim -M  [  ... ] 

Deliver a message, but only if the retry time has been reached:

root@localhost# exim -Mc  [  ... ] 

Force a message to fail and bounce as "cancelled by administrator":

root@localhost# exim -Mg  [  ... ] 

Remove all frozen messages:

root@localhost# exiqgrep -z -i | xargs exim -Mrm 

Remove all messages older than five days (86400 * 5 = 432000 seconds):

root@localhost# exiqgrep -o 432000 -i | xargs exim -Mrm 

Freeze all queued mail from a given sender:

root@localhost# exiqgrep -i -f luser@example.tld | xargs exim -Mf 

View a message's headers:

root@localhost# exim -Mvh  

View a message's body:

root@localhost# exim -Mvb  

View a message's logs:

root@localhost# exim -Mvl  

Add a recipient to a message:

root@localhost# exim -Mar  
... ]

Edit the sender of a message:

root@localhost# exim -Mes  

Access control

Exim allows you to apply access control lists at various points of the SMTP transaction by specifying an ACL to use and defining its conditions in exim.conf. You could start with the HELO string.

# Specify the ACL to use after HELO acl_smtp_helo = check_helo  # Conditions for the check_helo ACL: check_helo:      deny message = Gave HELO/EHLO as "friend"     log_message = HELO/EHLO friend     condition = ${if eq {$sender_helo_name}{friend} {yes}{no}}      deny message = Gave HELO/EHLO as our IP address     log_message = HELO/EHLO our IP address     condition = ${if eq {$sender_helo_name}{$interface_address} {yes}{no}}      accept 

NOTE: Pursue HELO checking at your own peril. The HELO is fairly unimportant in the grand scheme of SMTP these days, so don't put too much faith in whatever it contains. Some spam might seem to use a telltale HELO string, but you might be surprised at how many legitimate messages start off with a questionable HELO as well. Anyway, it's just as easy for a spammer to send a proper HELO than it is to send HELO im.a.spammer, so consider yourself lucky if you're able to stop much spam this way.

Next, you can perform a check on the sender address or remote host. This shows how to do that after the RCPT TO command; if you reject here, as opposed to rejecting after the MAIL FROM, you'll have better data to log, such as who the message was intended for.

# Specify the ACL to use after RCPT TO acl_smtp_rcpt = check_recipient  # Conditions for the check_recipient ACL check_recipient:      # [...]      drop hosts = /etc/exim_reject_hosts     drop senders = /etc/exim_reject_senders      # [ Probably a whole lot more... ] 

This example uses two plain text files as blacklists. Add appropriate entries to these files - hostnames/IP addresses to /etc/exim_reject_hosts, addresses to /etc/exim_reject_senders, one entry per line.

It is also possible to perform content scanning using a regex against the body of a message, though obviously this can cause Exim to use more CPU than it otherwise would need to, especially on large messages.

# Specify the ACL to use after DATA acl_smtp_data = check_message  # Conditions for the check_messages ACL check_message:      deny message = "Sorry, Charlie: $regex_match_string"     regex = ^Subject:: .*Lower your self-esteem by becoming a sysadmin      accept 

Fix SMTP-Auth for Pine

If pine can't use SMTP authentication on an Exim host and just returns an "unable to authenticate" message without even asking for a password, add the following line to exim.conf:

  begin authenticators    fixed_plain:   driver = plaintext   public_name = PLAIN   server_condition = "${perl{checkuserpass}{$1}{$2}{$3}}"   server_set_id = $2 >  server_prompts = : 

This was a problem on CPanel Exim builds awhile ago, but they seem to have added this line to their current stock configuration.

Log the subject line

This is one of the most useful configuration tweaks I've ever found for Exim. Add this to exim.conf, and you can log the subject lines of messages that pass through your server. This is great for troubleshooting, and for getting a very rough idea of what messages may be spam.

log_selector = +subject 

Reducing or increasing what is logged.

Disable identd lookups

Frankly, I don't think identd has been useful for a long time, if ever. Identd relies on the connecting host to confirm the identity (system UID) of the remote user who owns the process that is making the network connection. This may be of some use in the world of shell accounts and IRC users, but it really has no place on a high-volume SMTP server, where the UID is often simply "mail" or whatever the remote MTA runs as, which is useless to know. It's overhead, and results in nothing but delays while the identd query is refused or times out. You can stop your Exim server from making these queries by setting the timeout to zero seconds in exim.conf:

rfc1413_query_timeout = 0s 

Disable Attachment Blocking

To disable the executable-attachment blocking that many Cpanel servers do by default but don't provide any controls for on a per-domain basis, add the following block to the beginning of the /etc/antivirus.exim file:

if $header_to: matches "example\.com|example2\.com" then   finish endif 

It is probably possible to use a separate file to list these domains, but I haven't had to do this enough times to warrant setting such a thing up.

Searching the logs with exigrep

The exigrep utility (not to be confused with exiqgrep) is used to search an exim log for a string or pattern. It will print all log entries with the same internal message-id as those that matched the pattern, which is very handy since any message will take up at least three lines in the log. exigrep will search the entire content of a log entry, not just particular fields.

One can search for messages sent from a particular IP address:

root@localhost# exigrep '<= .* \[\] ' /path/to/exim_log 

Search for messages sent to a particular IP address:

root@localhost# exigrep '=> .* \[\]' /path/to/exim_log 

This example searches for outgoing messages, which have the "=>" symbol, sent to "user@domain.tld". The pipe to grep for the "<=" symbol will match only the lines with information on the sender - the From address, the sender's IP address, the message size, the message ID, and the subject line if you have enabled logging the subject. The purpose of doing such a search is that the desired information is not on the same log line as the string being searched for.

root@localhost# exigrep '=> .*user@domain.tld' /path/to/exim_log | fgrep '<=' 

Generate and display Exim stats from a logfile:

root@localhost# eximstats /path/to/exim_mainlog

Same as above, with less verbose output:

root@localhost# eximstats -ne -nr -nt /path/to/exim_mainlog

Same as above, for one particular day:

root@localhost# fgrep YYYY-MM-DD /path/to/exim_mainlog | eximstats


To delete all queued messages containing a certain string in the body:

root@localhost# grep -lr 'a certain string' /var/spool/exim/input/ | \                 sed -e 's/^.*\/\([a-zA-Z0-9-]*\)-[DH]$/\1/g' | xargs exim -Mrm 

Note that the above only delves into /var/spool/exim in order to grep for queue files with the given string, and that's just because exiqgrep doesn't have a feature to grep the actual bodies of messages. If you are deleting these files directly, YOU ARE DOING IT WRONG! Use the appropriate exim command to properly deal with the queue.

If you have to feed many, many message-ids (such as the output of an `exiqgrep -i` command that returns a lot of matches) to an exim command, you may exhaust the limit of your shell's command line arguments. In that case, pipe the listing of message-ids into xargs to run only a limited number of them at once. For example, to remove thousands of messages sent from

root@localhost# exiqgrep -i -f '' | xargs exim -Mrm 

Speaking of "DOING IT WRONG" -- Attention, CPanel forum readers

I get a number of hits to this page from a link in this post at the CPanel forums. The question is:

Due to spamming, spoofing from fields, etc., etc., etc., I am finding it necessary to spend more time to clear the exim queue from time to time. [...] what command would I use to delete the queue

The answer is: Just turn exim off, because your customers are better off knowing that email simply isn't running on your server, than having their queued messages deleted without notice.

Or, figure out what is happening. The examples given in that post pay no regard to the legitimacy of any message, they simply delete everything, making the presumption that if a message is in the queue, it's junk. That is total fallacy. There are a number of reasons legitimate mail can end up in the queue. Maybe your backups or CPanel's "upcp" process are running, and your load average is high -- exim goes into a queue-only mode at a certain threshold, where it stops trying to deliver messages as they come in and just queues them until the load goes back down. Or, maybe it's an outgoing message, and the DNS lookup failed, or the connection to the domain's MX failed, or maybe the remote MX is busy or greylisting you with a 4xx deferral. These are all temporary failures, not permanent ones, and the whole point of having temporary failures in SMTP and a mail queue in your MTA is to be able to try again after awhile.

Exim already purges messages from the queue after the period of time specified in exim.conf. If you have this value set appropriately, there is absolutely no point in removing everything from your queue every day with a cron job. You will lose legitimate mail, and the sender and recipient will never know if or why it happened. Do not do this!

If you regularly have a large number of messages in your queue, find out why they are there. If they are outbound messages, see who is sending them, where they're addressed to, and why they aren't getting there. If they are inbound messages, find out why they aren't getting delivered to your user's account. If you need to delete some, use exiqgrep to pick out just the ones that should be deleted.

Reload the configuration

After making changes to exim.conf, you need to give the main exim pid a SIGHUP to re-exec it and have the configuration re-read. Sure, you could stop and start the service, but that's overkill and causes a few seconds of unnecessary downtime. Just do this:

root@localhost# kill -HUP `cat /var/spool/exim/` 

You should then see something resembling the following in exim_mainlog:

pid 1079: SIGHUP received: re-exec daemon exim 4.52 daemon started: pid=1079, -q1h, listening for SMTP on port 25 (IPv4) 

Read The Fucking Manual

The Exim Home Page

Documentation For Exim

The Exim Specification - Version 4.5x

Exim command line arguments

Any questions?

Well, don't ask me! I'm one guy, with just enough time and Exim skills to keep my own stuff running okay. There are several (perhaps even dozens) of people on the Internet who know way more than me, and who are willing to help out random strangers. Check into the Exim users mailing list, or one of the many web-based gateways to that list. And good luck.

More notes

Thursday, October 20, 2011

drop role denied in postgres

Using postgres, I intended to drop the role 'paponte', but encountered the error:
# drop role paponte;
ERROR: role "paponte" cannot be dropped because some objects depend on it
DETAIL: 4 objects in database admision

Following (

I did
# drop owned by paponte;

And then no problem with:
# drop role paponte;

Sunday, October 16, 2011

hot to determine if a variable is set but has null value

This is an interesting issue... $a = null; isset($a) = false and $isset($b) = false...

I found this post:

From the isset() docs:

isset() will return FALSE if testing a variable that has been set to NULL.

Basically, isset() doesn't check for whether the variable is set at all, but whether it's set to anything but NULL.

Given that, what's the best way to actually check for the existence of a variable? I tried something like:

if(isset($v) || @is_null($v))

(the @ is necessary to avoid the warning when $v is not set) but is_null() has a similar problem to isset(): it returns TRUE on unset variables! It also appears that:

@($v === NULL)

works exactly like @is_null($v), so that's out, too.

How are we supposed to reliably check for the existence of a variable in PHP?

Edit: there is clearly a difference in PHP between variables that are not set, and variables that are set to NULL:

= array('b' => NULL);

PHP shows that $a['b'] exists, and has a NULL value. If you add:


you can see the ambiguity I'm talking about with the isset() function. Here's the output of all three of these var_dump()s:

array(1) {

Further edit: two things.

One, a use case. An array being turned into the data of an SQL UPDATE statement, where the array's keys are the table's columns, and the array's values are the values to be applied to each column. Any of the table's columns can hold a NULL value, signified by passing a NULL value in the array. You need a way to differentiate between an array key not existing, and an array's value being set to NULL; that's the difference between not updating the column's value and updating the column's value to NULL.

Second, Zoredache's answer, array_key_exists() works correctly, for my above use case and for any global variables:

(array_key_exists('a', $GLOBALS));
(array_key_exists('b', $GLOBALS));



Since that properly handles just about everywhere I can see there being any ambiguity between variables that don't exist and variables that are set to NULL, I'm calling array_key_exists() the official easiest way in PHP to truly check for the existence of a variable.

(Only other case I can think of is for class properties, for which there's property_exists(), which, according to its docs, works similarly to array_key_exists() in that it properly distinguishes between not being set and being set to NULL.)


Tuesday, June 21, 2011

cakephp multiple relations (hasmany primarykey)

×You have 1 new comment. See your responses.

Suppose (for lack of better example) I have a model Person and another model Twin (meaning a pair of twins). Twins has two Person foreign keys, say first_born_id and second_born_id referencing the id fields of two different people (in Person). How do I set up the relationships in cake?

I guess Twin would have something like:

$belongsTo = array('FirstBorn' => array('className' => 'Person',
'foreignKey' => 'firstborn_id'),
'SecondBorn' => array('className' => 'Person',
'foreignKey' => 'secondborn_id'));

But how should I set up Person? I could do it like:

$hasOne = array('TwinAsFirstborn' => array('className' => 'Twin',
'foreignKey' => 'firstborn_id'),
'TwinAsSecondborn' => array('className' => 'Twin',
'foreignKey' => 'secondborn_id'));

But then when I have a Person and I want to know about its twin I would need to check both relationships. I guess I am hoping there is a way to get a "Twin" relationship in Person representing any of the two ways a Person can be in a Twin relationship.

Or is there a better way to set this up?


add comment

2 Answers

up vote 1 down vote accepted

I agree with the Twin example being a little confusing. Let me assume that you have a Product model (Twin in your example) and it always has 2 Component models attached to it.

components: id - name
: id - component1_id - component2_id

I would set up Product as follows:

var $belongsTo = array(
'Component1' => array(
'className' => 'Component',
'foreignKey' => 'component1_id'
'Component2' => array(
'className' => 'Component',
'foreignKey' => 'component2_id'

And Component as:

var $hasMany = array(
'ProductWithComponentAsComponent1' => array(
'className' => 'Product',
'foreignKey' => 'component1_id'
'ProductWithComponentAsComponent2' => array(
'className' => 'Product',
'foreignKey' => 'component2_id'

Basically, you should replace your hasOne with hasMany. Each component hasMany products where it is the first component. At the same time, it hasMany products where it is the second component. Hope that makes things clear.

EDIT 1: (Oh, and "ProductWithComponentAsComponent#" is just for the purpose of explanation. You can keep whatever short, sweet alias you'd like depending on your actual models.)

EDIT 2: Simple rule of thumb for using hasOne relationships - Use it only when you're splitting a single table into many (like User/Profile)

EDIT 3: If you want all Products for a Component, then you can do this in two ways.

(A) Define the foreignKey as false in your hasMany relation.

var $hasMany = array(
'Product' => array(
'className' => 'Product',
'foreignKey' => false,
'conditions' => array(
'or' => array(
"Product.component1_id =",
"Product.component2_id ="

(B) If the above method does not work (Cake acts weird now and then), you can also use a join to make it obey. Create a function in the Component model like so:

function fetchProducts($id) {
if (!$id) {
return null;
return $this->Product->find('all', array(
'fields' => array('Product.*'),
'joins' => array(
'table' => 'components',
'alias' => 'Component',
'foreignKey' => false,
'type' => 'inner',
'conditions' => array(
'or' => array(
"Product.component1_id =",
"Product.component2_id ="
'' => $id

Maybe I misunderstand you, but the Component model represents an instance of a component (not a type of components) and a Component can only be part of one Product (also an instance, not a "class") either as component1 or component2. So shouldn't the relationship be hasOne? Also, with your Component model (basically same as mine in the first example, except for hasOne->hasMany) the problem remains about how to access the Product of a Component without having to check both relationships (I might not care if the Component is a component1 or component2 of the Product).zephyr Jan 5 at 20:58

You can replace Component with ComponentInstance if you like. Refer to Edit 2 regarding hasOne: Use it primarily when splitting tables. To access all Products of a component, refer to Edit 3. :)RabidFire Jan 6 at 2:56

Ah. I didn't know you could set foreignKey to false (is this documented somewhere?). However it seems to break recursiveness. With recursive set to 2 for the Component I get an "Unknown column: in WHERE clause" error as the Component is not present in the separate queries (from recursiveness) on Product. For regularly declared foreignKey relationships these type of queries get the id as a constant (e.g. "(3)" instead of "'Component'.'id'"). One could do something like your method B, but I had hoped that there was a way that integrates better with the rest of the CakePHP system.zephyr Jan 6 at 11:48

Yea, as I mentioned, Cake acts weird at times! Use the Containable behavior instead of recursive. Apart from that, I guess you're good to go! :)RabidFire Jan 6 at 13:00

Yes, I can avoid the problem with Containable, but I still won't be able to (automagically) get the models related to the Product as if it was a regularly defined foreignKey relationship. Maybe I can do something with afterFind in Component, but it will probably feel a bit hackish (I would have to avoid auto recursion with Containable, and then get it anyway with afterFind.. or something.). Thank you for your help!zephyr Jan 6 at 16:00

add comment

Why would you define a twin like this?

A twin, first or second born is a person. The thing that associates them with a parent is the fact they are a "child" and their "DOB" is the same.

So would you not do something like:

Person -> ID, Name, Age, DOB, Parent_ID

The parent_ID is stored into the childs record, and the twin is determined by comparing all children under a parent for DOB?

Does this make it any easier to set up your cakePHP relationships?


Ah, well I guess my example was not too well chosen. In the real application Person is a type of component and Twin is a product made up of two of these components (or possibly only one of them actually). So the two "person"s have no other connection than that they together make up a pair of "twin".zephyr Jan 5 at 13:30

Ahhh I see - and does this "bundle" of components only ever have 2 records? Are you able to post your current Data Structure?diagonalbatman Jan 5 at 13:32

Yes, there can only be two components (and they have different roles in the product, so they are differentiated by their role as well, hence the "firstborn" and "secondborn" in the example). I can't post the actual code but the Models look exactly like in the example (plus some unrelated stuff). The component database table has an "id" field, and the product table has two foreign key fields ("component_a_id" and "component_b_id") both referencing the component "id" field.zephyr Jan 5 at 13:46

add comment

Your Answer

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

send mail from console using Mutt

Sending email or mail with attachment from command or shell prompt

by nixcraft on August 13, 2004 · 79 comments

If you are looking to send email with attachment via shell script or at shell prompt/command line (read as bash prompt), use mutt command.

Mutt is a small but very powerful text based program for reading electronic mail under UNIX /Linux operating systems, including support for color terminals, MIME, and a threaded sorting mode.

Please note that mutt is a pure MUA and cannot send e-mail without proper email server . You need a working Mail Transfer Agent (MTA) such as sendmail or postfix. I am assuming that you have configured email server.

Install mutt

If mutt is not installed, use apt-get or yum or up2date command as follows (login as a root user):

(A) Debian Linux / Ubuntu Linux user use following command to install mutt:
# apt-get install mutt

B) Fedora / CentOS or Red Hat Linux (RHEL) user can use following command to install mutt:
# yum install mutt
# up2date mutt

C) FreeBSD user use following command to install mutt via pkg_add command:
# pkg_add -v -r mutt

How do I send email attachments from a command prompt?

1) Use mutt command as follows to send an email with attachment:
$ mutt -s "Test mail" -a /tmp/file.tar.gz < /tmp/mailmessage.txt


  • - is the recipient
  • /tmp/mailmessage.txt - is the main body of the e-mail (read message from the file "mailmessage.txt")
  • /tmp/file.tar.gz - is an attachment (with option -a)
  • "Test mail" - is a subject line (option -s)

See also:

Featured Articles:

{ 77 comments… read them below or add one }

1 Anonymous November 2, 2004

I didnt recieve any mail in my yahoo inbox when i tried to send the message from the command line using mutt
mutt -s “testmail” > /tmp/k
please i am eager to know about it


2 Julio Virea May 1, 2011

Check your bulk mail. I am using it and my emails when are sent out of the computer goes in the “from: www-data” so yahoo take the email as spam and if your settings in is to delete all spam then is deleting it. Try using another email a POP account. It will work like charm.


3 nixcraft November 18, 2004

May be yahoo is blocking your email! It should work. If you are on PPP then it is high possiblity!

Vivek Gite


4 Anonymous April 10, 2005

I can’t be sure, but it looks like you’re using the wrong directional switch. In your command use, you have “>”. I’m presuming you’re attempting to send the message in the file /tmp/k which means you should probably be using the “


5 nixcraft April 11, 2005

In the command:

mutt -s “Test mail” -a /tmp/file.tar.gz


6 Anonymous July 23, 2005

Hey i was hunting 4 this info and found it via yahoo. This is easy than those crazy scripts… thx for good info in this blog.


7 tony jr. July 24, 2005

thanks this blog is bookmarked now.


8 Anonymous August 19, 2005

thanks, you made my day (or better, tomorow ) with this hint…


9 Anonymous November 19, 2005

nice post worth to bookmark :)


10 ebasi December 19, 2006

thanks for this post!


11 Hagel April 28, 2007

How do I use MUTT to send multiple attachments in a single email?


12 MickZA May 23, 2007

Multiple attachments use -a for each ie:

mutt -s “Test Mail” -a attach1 -a attach2 -a attach3


13 AJS June 6, 2007

Nice post thanks guys!


14 kumaryadav July 31, 2007

I just want learn more things in linux,


15 Mary Killpatrick August 7, 2007

How do you send an e-mail to multiple recipients with mutt?


16 aaron December 11, 2007

is the reading in of the text file required or can I type a one-line body from the command line?


17 Sue December 12, 2007

This is a reply to message 12, regarding using “-a” to send multiple attachments in one email.

I use the same mutt command line in my script. My challenge is I can’t hard code the files with “-a”. I need to search for all logs, find out what they are and mutt them.

I need something like:

mutt -s “log files” -a *.log < summary

How do I code “-a *.log”?


18 Barry December 17, 2007

Reply to #17: Regarding how to use “-a” for an indeterminate number of attachments; here’s one way:

for x in $(ls -1 *.log) ; do
y=”$y -a $x”

mutt -x “subject” $y < somefile


19 bhush April 3, 2008

How do you send an e-mail to multiple recipients with mutt?


20 gpsforum May 1, 2008

In reply to 19: Putting all addresses into quotes should work.

mutt -s “My message” -a attchmnt “address1 address2″


21 macs June 5, 2008

its working well in system which serve as proxy but not working from my desk. How to get it work in a proxy ed network ?


22 Rob June 27, 2008

Thanks, I was searching for an hour for this! To do the equivalent with sendmail is crazy!


23 zyga August 27, 2008

man mpack


24 Nokao September 16, 2008

Thank you!


25 Carlos Garcia October 27, 2008

worked like a charm for me, thanx guys :]


26 Malath October 31, 2008

hi all, i am getting this error
mutt -s “Test Shell Mail” < email
Error sending message, child exited 127 (Exec error.).
Could not send the message.


27 Kaniska November 1, 2008

How to use mapck to send multiple files? i am able to send only one file with the command. Please help


28 vivek November 1, 2008
29 Shamjith December 13, 2008



30 ace December 21, 2008

i am unable to send mail from shell .. getting an error /etc/postfic/ no such file or directory ..pls help


31 EMG January 12, 2009

I am unable to send an .htlm file as the mail body. When I use the command below, it mails the actual code.

mutt -s “Test Mail” < mail_attachment.html

I can send it as an attachment and it comes through fine with this command:

mutt -s “Test Mail” -a mail_attachment.html < mail_body.txt

the mail_body.txt does not contain anything. I just get the attachemnt. Sun system can e-mail it to Outlook as an .htlm mail.


32 jesper hansen January 19, 2009

Hmmm why all this reported succes, I seem to get it all wrong.

mutt -s “test Mail” -a /home/jesper/Y.tar < t.txt

so where am I going wrong?

I am using a laptop with wireless connection. How do I specify “from”?


33 Sam February 12, 2009

Is it possible to send specific text in the body of the mail, rather than sending the body from the attached file?

mutt -s “Test Mail” -a /home/test.txt < “TEXT BODY”


34 tarun singhal March 4, 2009

is it possible to set “from” option, becouse by default i getting from: root
i using command like:—
mutt -s ‘Test mail’ -a file.xls < file

i want from option should become useranem who is giving mail to someone


35 jiltin April 9, 2009

you can use uuencode too. Here is an example I used for many years. How to extract,using bash/unix/linux shell scripting, the oracle data like excel report and …->


36 Prudhvi raj May 15, 2009

if u want to send certian text in body instead of using a body file then go for this:
#> echo -e “This is the body message of the email” | mutt -a server.key -s “This is the email subject”


37 Amritesh June 18, 2009

Actually I am using proxy server to access internet
i did
export http_proxy=””
export http_proxy=
to configure proxy
mutt -s “Test mail” -a /root/amritesh/rs.txt < /root/amritesh/gw.txt
to send mail but it wont work plz guide me what to do…?


38 Tom July 4, 2009

in debian lenny:
mutt -s “subject” -a file1 file2 file3 — < email-text.file

between attachments and recipients need to putt double dash and files for attachment with out anything

with out double dash wroute:
"Can't stat No such file or directory unable to attach file."

because it's thinking that it's one more attachemt file )))

Hope it's help you )))


39 phil January 27, 2011

“in debian lenny:
mutt -s “subject” -a file1 file2 file3 — < email-text.file

between attachments and recipients need to putt double dash and files for attachment with out anything"

same for squeeze. thanks mate


40 ram July 29, 2009


when i am sending a mail with pdf attachment thru mailx utility on MS Outlook than it wooks fine but whenver i am sending the same to rediff/gamil/yahoo than instead of pdf attachment it is sending junk characters,please advice.
uuencode xx_file.pdf xx_file.pdf| mailx –s “Subject of mail” “mail_id”
i am using the above command.

please suggets to do the same.



41 Murali September 16, 2009


This e-mail (mutt) utility looks very useful, I would like to use it on AIX, can any one let me know how I could install this utility on AIX and use it.

Thank you



42 Sanil October 6, 2009

if you want to send the contents of a text file from the shell prompt do the following.

# mail -s “subject of the mail” < textfile.txt


43 lien October 6, 2009

What an excellent tool. I have been looking for something like this for ages!


44 Fun Nepali Games October 13, 2009

How to specify “from name” when sending email thru mutt? I am using php cli to send email and I could only set the “from email”, and not the “from name”. Here is my php statement with mutt command:

shell_exec(“export EMAIL=\”\”; echo ‘email text’ | mutt -s ‘email subject’ -a ‘/attachment/file.pdf’“);

When I ran this php program, the recepient receives email like this:
From: “My Real Name”

But I want “My Company Name” to show in the From: line. Where to specify this when running mutt ?


45 Maroun October 26, 2009


I need a favor, I am using mutt command to send an email and everything is working fine, but as you know when email arrived to the proper person, the email is coming from internal name of the instance of the server (e.g From: XX@servername.companyname.extension), can we put an constanct alias for ‘from email account’, I mean from: for example. I think this is an internal linux parameters structure?



46 Ken November 12, 2009

Hi Fun Nepali Games/ Maroun,

Use this command format to set the from name and the from email to whatever you want:
export EMAIL=’from name<from email address>’; echo ‘email body text‘ | mutt -a ‘attachment file‘ -s ‘subjectrecipient address

Hope I helped! Greetings


47 Fun Nepali Games November 12, 2009

Hi Ken, thank you for your help. I had come up with this syntax to fix my issue.

shell_exec(”export EMAIL=\”\”; export REPLYTO=\”\”; echo ‘email text’ | mutt -n -e ‘set envelope_from_address=\”\”‘ -e ‘set realname=\”My Company Name\”‘ -s ‘email subject’ -a ‘/attachment/file.pdf’“);


48 vrc November 15, 2009

I am working on ubuntu. i did install mutt and when i typed mutt -s “hello” in my terminal a nano editor came up and i manually had to proceed the process of sending the mail…finally it attached a file from my /tmp folder in which the contents were buffered and this file was sent…
i just want to automate the entire process without any human intervention…
Can someone please help me out in automating the entire process…


49 Andres Kwan November 27, 2009

Thanks guys, with your help I did solve the problem
“Can’t stat No such file or directory unable to attach file.”


50 Paul January 17, 2010

How can you mutt only the newest file from a particular directory in a bash script?


51 lsi January 30, 2010

hey nice thread, i got this working with from field set as I desire, from a shell script as follows:

export EMAIL="My Name "
export REPLYTO="email@protected"
echo "body text" | mutt -e 'set envelope_from' -a /filename.gif -s "subject" ${TARGETEMAIL}


52 lsi January 30, 2010

(note, board munged code a bit, try again:

export EMAIL=”My Name “


53 lsi January 30, 2010

attempt 3:

export EMAIL=”My Name

eg. it is “My Name (less-than-sign)email@protected(greater-than-sign)”


54 Gavrilo Princep February 26, 2010

Just spent a couple of hours working this out.

The mutt way to set the from address and name in mutt is ;

mutt -e "unmy_hdr from; my_hdr From:\"
-e "set realname=\"Ronald McDonald\" " \
-s "this is the subject line ... " \
-a attachmentfile.txt -a anotherFile.doc\
-- < bodyOfEmail.txt

Note that the -e “command” lets you do any set, unsets, or mutt configurations


For the record, the other approaches to customising From addresses (and by extention other attributes) are as follows.

I have listed all the methods that mutt make available, though two of them don’t work.

Method 3 works, #2 half works, method #1 and 4 don’t work.

#from method #1
set use_envelope_from=yes
set envelope_from_address=""
# NOTE : use_from defaults to yes, so that mutt forces the from address

# from method #2 :
# use_from=no works. Now the MTA, e.g. ssmtp sets the from address
set use_from=no
# however, the set_from DOESNT WORK.
set from="" # doesn't work

# from method #3
# this is the approach to use. See my command line example
# you must use the my_hdr to set a new from address. See 4
unmy_hdr from
my_hdr From:""

# from method #4 : let the MTA set the from address
# doesn't work. Mutt fails to remove the from header line.
unmy_hdr from


55 Gavrilo Princep February 26, 2010

forgot to add, these are all edits to the /etc/Muttrc file, or your .muttrc equavalent


56 Yosi March 15, 2010

Thanks for the article, helped me a lot. (the sending part)



57 Deepak Kandpal April 8, 2010

Hi Friends…

I have a requiremnt where i need to send a mail with an attachement (pdf file) for the same i have written this code and it is getting executed without any error but still i am not receiving any mail. Please adive:

Following code is for you reference:

DATETIME=`date “+%Y%m%d%H%M%S”`
DATETIME1=`date “+%Y%m%d”`

REQUESTID=echo $1 | awk ‘{print $2}’ – | sed ‘s;FCP_REQID=;;’
USERPASS=echo $1 | awk ‘{print $3}’ – | sed ‘s;FCP_LOGIN=;;’ | sed ‘s;”;;g’
P_FILE_PATH=echo $1 | awk ‘{print $9}’ – | sed ‘s;”;;g’
P_FILE_NAME=echo $1 | awk ‘{print $10}’ – | sed ‘s;”;;g’
P_USER_EMAIL_ID=echo $1 | awk ‘{print $11}’ – | sed ‘s;”;;g’
FILE_SUB=echo $1 | awk ‘{print $12}’ – | sed ‘s;”;;g’

# “/oracle/apps/inst/apps/TEST_erpapts2/logs/appl/conc/out XXADIB_PO_STANDARD_467106_1.PDF temp1@adibdev.local testmail”

echo “——————————————–”
echo “DatTime=” $DATETIME
echo “——————————————–”
echo “param=” $1
echo “——————————————–”
echo ” ”
echo “——————————————–”
echo $FILE_SUB
echo “——————————————–”
echo ” ”
echo “Just before sending mail..”
echo ” ”
echo “——————————————–”
if test $EXIT_STATUS = 0 ; then
echo “Success”
(echo “Please find the enclosed all vacancies and the details of vacacy statues. This is system generated email. Please do not reply.”;uuencode $P_FILE_PATH $FILE_SUB) | mailx -s “$FILE_SUB – on $DATETIME” $P_USER_EMAIL_ID
echo “Fail”
echo “——————————————–”
echo ” ”
echo “Un-successful run of the Error Log File”
echo ” ”
echo “——————————————–”
echo “——————————————————-”
exit 0


58 Gavrilo Princep April 9, 2010

(1) have you considered looking at the examples in this thread ?
(2) this thread is about mutt, and you are using mailx
(3) my example above shows how to send an email of any configuration, with any attachments, from the command line, using mutt

In general, do this :
add the
line /bin/bash -x
to the start of your scripts. NOTE THE -x
Then watch the output, it will show you all the assignments. You probably have made a mistake in one of your awk assignments.
Also don’t try to be smart, doing stuff like running multiple commands in a subshell (in brackets) and then piping the result to mailx. Instead do clear, seperate steps, and write temporary files, in testing AND PRODUCTION so you can investigate what is going on. I mean you haven’t even been able to narrow the problem down to the step that is going wrong.

The answer to why this isn’t working is that, probably, your don’t have a MTA running. mutt and mailx and manyothers just manage the generation of the email, you need a MTA (mail transfer agent) like ssmtp (simple, easy, great) or exim4 (not simple, fully featured)

—-in summary: —-
use /bin/bash -x
test each intermediate step
use mutt, and copy one of the examples above.
find where the error is BEFORE you post on a forum.


59 Edmund Doyle June 1, 2010

I type in this text “$ mutt -s “Test mail” -a msg.txt < msn.txt" and i end up with "$" is not recognized yet when i use the sample code($ mutt -s "Test mail" -a /tmp/file.tar.gz < /tmp/mailmessage.txt) it works except for the file not specified part which was expected


60 Gavrilo Princep June 1, 2010

It’s an idiom: the “$” is used by some people to represent the prompt character In a terminal, shorthand for I-am-typing-in-a-terminal-here. I think that they use “$” to represent the root user, and # to represent the prompt of a normal user.

Just ignore it….
…. and the rest works … right ? … cool.

Depending on permissions, doesn’t have to be a root user,


61 Oystein July 16, 2010

The other way around. # means root, $ means a normal user.


62 Edmund Doyle June 1, 2010

Thank you for commenting however i’m begining to think that my computer doesn’t support mutt. Is this specifically for linux users because there is no mutt install link that works with my computer.


63 Jonathan Walsh July 20, 2010

What operating system is your computer running Edmund?


64 Timmy! July 20, 2010

Ubuntu 10.04 mutt bug – add “–” after attachment, even only one file.


65 Cybergavin September 10, 2010

Thank you Vivek. This came handy when I realized that I didn’t have the sharutils package (for uuencode) installed and so could not use mailx/uuencode combination. Anyway, the “-a” option of mutt is better than mailx/uuencode.


66 thenoid January 29, 2011

Hey, thanks, I needed to send a quick mail and your tip worked like a charm — except I needed to send two attachments and mutt required a — before the destination. Thanks!


67 Kalycs March 2, 2011

Recently I have installed Linux Ubuntu on my Laptop and was trying some command line to send emails. I do not know what package needs to be installed but same command is working fine at my work place which has Unix AIX machine.

For example this syntax is working at my work place but not working on my Ubuntu command prompt.
(echo “test”;) | mail -r -s “Send Email ”

Can somebody please advice what do I need to do if I want to use these above options.

Thanks in Advance


68 Bartox March 8, 2011

I am not able to send more than ~7Mb (+ headers info which become in a 9.9 Mb file size). How can I increase the attachment size sent via mutt?. I’ve looking at the conf file and I didn’t see any line where the ~10 Mb file size attachments were set by default. I really need to increase this thing at least 25 Mb to send database backups to my email account (which supports 50 Mb attachments).


69 Edmund March 11, 2011

Is it zipped?


70 Bartox March 15, 2011

Yes, I forgot to mention it’s a file compressed with LZMA algorithm which is the highest compression level around. My server OS is Linux/RedHat. I just need to know if mutt is capable to send bigger than ~10 MB attachment, the current backup file that I am getting is about ~7 Mb but with headers it just become into a 10 Mb. As I said I research about it, I read the config file and nothing yet.
Appreciate your help.


71 Edmund March 15, 2011

Ha Ha Ha ! excuse me, Not laughing at you but that was just a suggestion, you obviously kno much more than me.


72 Bartox March 19, 2011

Actually I was looking at the wrong place. The attachment size limit is not controlled by mutt else the smpt server itself, in my case postfix.

If somebody is having this same issue, just go the postfix config file at /etc/postfix/ (on RedHat based kernels) and look for this directive: message_size_limit (or add it to the end if it’s not in there) and just increase the value to: message_size_limit = 20480000 (20 MB for example).

Hope that helps.


73 Edmund March 15, 2011

can this run as a portable application from a UNC path


74 Martin May 18, 2011

Is it possible to specify a different name for an attachment than the actual file name? For instance, we have many programs the call the mutt command and send files with extensions that our recipient’s PCs don’t recognize. It would be nice to be able to rename the attachment in mutt without having to actually modify the source file.




75 SqueezeOJ June 18, 2011

How do I use a Variable Subject. For example:

#!/bin/bash mySUBJECT="No Errors in Log File" mutt -s "$mySUBJECT" < Nightly-Backup-Log.txt exit 0 

This always hangs and thus fails. But typing-in the same string where $mySUBJECT is works fine. Could someone tell me what I'm doing wrong?



76 SqueezeOJ June 18, 2011

Answered my own question!

Need to use Single Quotes rather than Double Quotes around $mySUBJECT. For example this works:

#!/bin/bash mySUBJECT=”No Errors in Log File” mutt -s '$mySUBJECT' < Nightly-Backup-Log.txt exit 0 

Hope it helps someone!


77 JULIO VEIRA June 19, 2011

The mutt program is super cool this line is part of a script I did that make a backup of all my SQL Server Info and send it to my email. Because I have a High protection for Spam this email always go to junk. I also got a POP3 account in my work and there I have no problem also I receive it in my iPhone 3GS. This is the hell of a tool. THanks for sharing this with us.

#Email will be send to my account. mutt -s "MySql Server Database backup files" < /home/julio/dbbak/message.txt -a /home/julio/dbbak/ #Email will be send to my pop3 company account. mutt -s "MySql Server Database backup files" < /home/julio/dbbak/message.txt -a /home/julio/dbbak/ 


Leave a Comment

You can use these HTML tags and attributes for your code and commands:

Previous post:

Next post: