The `pipe' transport is used to deliver messages via a pipe to a command running in another process. This can happen when an address is expanded via an alias, filter, or forward file, or when a director or explicitly directs the message to a pipe transport. A `pipe' transport can also be used via a router as a pseudo-remote transport for passing messages for remote delivery by some means other than Exim.
As `pipe' is a local transport, it is always run in a separate process, normally under a non-privileged uid and gid. In the common case, these are the uid and gid belonging to the user whose `.forward' file directed the message at a pipe. However, in other cases the uid and gid may be specified explicitly. Current and `home' directories are also controllable. See chapter "Environment for running local transports" for details of the local delivery environment.
If the command exits with a non-zero return code, the delivery is deemed to have failed, unless either the `ignore_status' option is set (in which case the return code is treated as zero), or the return code is EX_TEMPFAIL, which is interpreted as meaning `try again later'. Many Unix systems define EX_TEMPFAIL in `sysexits.h', and they all seem to use a value of 75. For those systems that don't have EX_TEMPFAIL, Exim assumes that a value of 75 has this meaning.
The `return_output' option can affect the result of a pipe delivery. If it is set and the command produces any output on its standard output or standard error files, it is considered to have failed, even if it gave a zero return code or if `ignore_status' is set. The output from the command is sent as part of the delivery failure report. However, if `return_fail_output' is set, output is returned only when the command exits with a failure return code, that is, a value other than zero or EX_TEMPFAIL.
By default, the command line is broken down into a command name and arguments by the `pipe' transport. The `allow_commands' and `restrict_to_path' options can be used to restrict the commands that may be run. Unquoted arguments are delimited by white space; in double-quoted arguments, backslash is interpreted as an escape character in the usual way. This does not happen for single-quoted arguments.
String expansion is applied to the command line except when it comes from a traditional `.forward' file (commands from a filter file are expanded). The expansion is applied to each argument in turn rather than to the whole line. Thus the number of arguments cannot be changed as a result of string expansion, and quotes or backslashes in inserted variables do not interact with external quoting.
Special handling takes place when an argument consists precisely of the text `$pipe_addresses'. This is not a general expansion variable; the only place this string is recognized is when it appears as an argument for a pipe or transport filter command. It causes each address that is being handled to be inserted in the argument list at that point as a separate argument. This avoids any problems with spaces or shell metacharacters, and is of use when a `pipe' transport is handling groups of addresses in a batch (see the `batch' option below).
The resulting command is then run directly from the transport, with the message supplied on the standard input, and the standard output and standard error both connected to a single pipe that is read by Exim. The `max_output' option controls how much output the command may produce, and the `return_output' and `return_fail_output' options control what is done with it.
The command is not (by default) run under a shell. This lessens the security risks in cases when a command from a user's filter file is built out of data that was taken from an incoming message. If a shell is required, it can of course be explicitly specified as the command to be run. However, there are circumstances where existing commands (for example, in `.forward' files) expect to be run under a shell and cannot easily be modified. To allow for these cases, there is an option called `use_shell', which changes the way the `pipe' transport works. Instead of breaking up the command line as just described, it expands it as a single string and passes the result to `/bin/sh'. The `restrict_to_path' option and the `$pipe_addresses' facility cannot be used with `use_shell', and the whole mechanism is inherently less secure.
The following environment variables are set up when the command is invoked:
DOMAIN the local domain of the address HOME the `home' directory -- see below HOST the host name when called from a router LOCAL_PART see below LOGNAME see below MESSAGE_ID the message's id PATH as specified by the `path' option below QUALIFY_DOMAIN the configured qualification domain SENDER the sender of the message SHELL /bin/sh USER see below
When a `pipe' transport is called directly from (for example) a `smartuser' director, then LOCAL_PART is set to the local part of the address. When it is called as a result of a forward or alias expansion, LOCAL_PART is set to the local part of the address that was expanded. LOGNAME and USER are set to the same value as LOCAL_PART for compatibility with other MTAs.
HOST is set only when a `pipe' transport is called from a router as a pseudo-remote transport (for example, for handling batched SMTP). It is set to the first host name specified by the router (if any).
If the transport's `home_directory' option is set, then its value is used for the HOME environment variable. Otherwise, certain directors may set a home directory value, as described in chapter "Environment for running local transports".
Option: allow_commands
The string is expanded, and then is interpreted as a colon-separated list of
permitted commands. If `restrict_to_path' is not set, then the only commands
permitted are those in the `allow_commands' list. They need not be absolute
paths; the path option is still used for relative paths. If
`restrict_to_path' is set with `allow_commands', then the command must
either be in the `allow_commands' list, or a name without any slashes that is
found on the path. In other words, if neither `allow_commands' nor
`restrict_to_path' is set, there is no restriction on the command, but
otherwise only commands that are permitted by one or the other are allowed. For
example, if
and `restrict_to_commands' is not set, the only permitted command is
`/usr/ucb/vacation'. The `allow_commands' option may not be set if
`use_shell' is set.
allow_commands (pipe) option
Type: string
Default: unset
allow_commands = /usr/ucb/vacation
Option: batch
Type: string
Default: "none"
Normally, each address that is directed or routed to a `pipe' transport is handled separately. In special cases it may be desirable to handle several addresses at once, for example, when passing a message with several addresses to a different mail regime (for example, UUCP). If this option is set to the string `domain', then all addresses with the same domain that are directed or routed to the transport are handled in a single delivery. If it is set to `all' then multiple domains are batched. The list of addresses is included in the `Envelope-to:' header if `envelope_to_add' is set (see below). The addresses can also be set up as separate arguments to the pipe command by means of the specially-recognized argument `$pipe_addresses' (see above). Otherwise, the only difference between this option and `bsmtp' is the inclusion of SMTP command lines in the output for `bsmtp'.
Option: batch_max
Type: integer
Default: 100
This limits the number of addresses that can be handled in a batch, and applies to both the `batch' and the `bsmtp' options.
Option: bsmtp
Type: string
Default: "none"
This option is used to set up a `pipe' transport as a pseudo-remote transport for delivering messages in batch SMTP format for onward transmission by some non-Exim means. It is usually necessary to suppress the default settings of the `prefix' and `suffix' options when using batch SMTP. The value of the option must be one of the strings `none', `one', `domain', or `all'. The first of these turns the feature off. A full description of the batch SMTP mechanism is given in section "Outgoing batched SMTP" in chapter "SMTP processing". When `bstmp' is set, the `batch' option automatically takes the same value. See also the `use_crlf' option.
Option: bsmtp_helo
Type: boolean
Default: false
When this option is set, a HELO line is added to the output at the start of each message written in batch SMTP format. Some software that reads batch SMTP is unhappy without this.
Option: command
Type: string
Default: unset
This option need not be set when `pipe' is being used to deliver to pipes obtained from address expansions (usually under the instance name `address_pipe'). In other cases, the option must be set, to provide a command to be run. It need not yield an absolute path (see the `path' option below). The command is split up into separate arguments by Exim, and each argument is separately expanded. Both single and double quotes are recognized. In double-quoted arguments, backslash is an escape character in the usual way. If a shell is required, it must be explicitly requested, as the command is not run under a shell by default.
Option: current_directory
Type: string
Default: unset
If this option is set, it specifies the directory to make current when running the delivery process. The string is expanded at the time the transport is run. If this is not set, the current directory is taken from data associated with the address. See chapter "Environment for running local transports" for full details of the local delivery environment.
Option: delivery_date_add
Type: boolean
Default: false
If this option is true, a `Delivery-date:' header is added to the message. This gives the actual time the delivery was made. As this is not a standard header, Exim has a configuration option (`delivery_date_remove') which requests its removal from incoming messages, so that delivered messages can safely be resent to other recipients.
Option: directory
Type: string
Default: unset
This option was made obsolete by the introduction of the separate options `current_directory' and `home_directory'. If encountered, it is treated as synonymous with `home_directory'.
Option: envelope_to_add
Type: boolean
Default: false
If this option is true, an `Envelope-to:' header is added to the message. This gives the original address(es) in the incoming envelope that caused this delivery to happen. More than one address may be present if `batch' or `bsmtp' is set, or if more than one original address was aliased or forwarded to the same final address. As this is not a standard header, Exim has a configuration option (`envelope_to_remove') which requests its removal from incoming messages, so that delivered messages can safely be resent to other recipients.
Option: freeze_exec_fail
Type: boolean
Default: false
Failure to exec the command in a pipe transport is by default treated like any other failure while running the command. However, if `freeze_exec_fail' is set, failure to exec is treated specially, and causes the message to be frozen, whatever the setting of `ignore_status'.
Option: from_hack
Type: boolean
Default: false
If this option is true, lines in the body of the message that start with the string `From ' are modified by adding a right angle-bracket at their start. This is necessary for traditional BSD-format mailboxes, where such lines might otherwise indicate the start of a new message.
Option: group
Type: string
Default: unset
If this option is set, it specifies the group under whose gid the delivery process is to be run. If it is not set, a value associated with a user may be used (see below); otherwise a value must have been associated with the address by the director which handled it. If the string contains no $ characters, it is resolved when Exim starts up. Otherwise, the string is expanded at the time the transport is run, and must yield either a digit string or a name which can be looked up using `getgrnam()'.
Option: home_directory
Type: string
Default: unset
If this option is set, its expanded value is used to set the HOME environment variable before running the command. This overrides any value that is set by the director. If no current directory is supplied by the director or the transport, the home directory value is used for that as well. See chapter "Environment for running local transports" for details of the local delivery environment.
Option: ignore_status
Type: boolean
Default: false
If this option is true, the status returned by the subprocess that is set up to run the command is ignored, and Exim behaves as if zero had been returned. Otherwise, a non-zero status causes an error return from the transport unless the value is EX_TEMPFAIL, which causes the delivery to be deferred and tried again later.
Option: initgroups
Type: boolean
Default: false
If this option is true and the uid for the local delivery is specified by the `user' option, then the `initgroups()' function is called when running the transport to ensure that any additional groups associated with the uid are set up.
Option: log_defer_output
Type: boolean
Default: false
If this option is set and the status returned by the command is EX_TEMPFAIL and any output was produced, the first line of it is written to the main log.
Option: log_fail_output
Type: boolean
Default: false
If this option is set and the command returns any output and also ends with a return code that is neither zero nor EX_TEMPFAIL, the first line of output is written to the main log.
Option: log_output
Type: boolean
Default: false
If this option is set and the command returns any output, the first line of output is written to the main log, whatever the return code.
Option: max_output
Type: integer
Default: 20K
This specifies the maximum amount of output that the command may produce on its standard output and standard error file combined. If the limit is exceeded, the process running the command is killed. This is intended as a safety measure to catch runaway processes. The limit is applied whether any `return_output' option is set or not. Because of buffering effects, the amount of output may exceed the limit by a small amount before Exim notices.
Option: path
Type: string-list
Default: "/usr/bin"
This option specifies the string that is set up in the PATH environment variable of the subprocess. If the `command' option does not yield an absolute path name, the command is sought in the PATH directories, in the usual way.
Option: pipe_as_creator
Type: boolean
Default: false
If `user' is not set and this option is true, then the delivery process is run under the uid that was in force when Exim was originally called to accept the message. If the group id is not otherwise set (via the `group' option above, or by the director that processed the address), then the gid that was in force when Exim was originally called to accept the message is used. Setting this option may be necessary in order to get some free-standing local delivery agents to work correctly. Note, however, that the `never_users' configuration option overrides.
Option: prefix
Type: string
Default: "see below"
The string specified here is expanded and output at the start of every message. The default is the same as for the `appendfile' transport, namely
prefix = "From ${if def:return_path{$return_path}{MAILER-DAEMON}}\ ${tod_bsdinbox}\n"
This is required by the commonly used `/usr/ucb/vacation' program,
but it must not be present if delivery is to the Cyrus IMAP server.
It can be suppressed by setting
This is also usually necessary when doing batch SMTP deliveries.
prefix =
Option: restrict_to_path
Type: boolean
Default: false
When this option is set, any command name not listed in `allow_commands' must contain no slashes. The command is searched for only in the directories listed in the `path' option. This option is intended for use in the case when a pipe command has been generated from a user's `.forward' file. This is usually handled by a `pipe' transport called `address_pipe'.
Option: retry_use_local_part
Type: boolean
Default: true
When a local delivery suffers a temporary failure, both the local part and the domain are normally used to form a key that is used to determine when next to try the address. This handles common cases such as exceeding a quota, where the failure applies to the specific local part. However, when local delivery is being used to collect messages for onward transmission by some other means, a temporary failure may not depend on the local part at all. Setting this option false causes Exim to use only the domain when handling retries for this transport.
Option: return_fail_output
Type: boolean
Default: false
If this option is true, and the command produced any output and ended with a return code other than zero or EX_TEMPFAIL, the output is returned in the delivery error message. However, if the message has a null sender (that is, it is a delivery error message), output from the command is discarded.
Option: return_output
Type: boolean
Default: false
If this option is true, and the command produced any output, the delivery is deemed to have failed whatever the return code from the command, and the output is returned in the delivery error message. Otherwise, the output is just discarded. However, if the message has a null sender (that is, it is a delivery error message), output from the command is always discarded, whatever the setting of this option.
Option: return_path_add
Type: boolean
Default: false
If this option is true, a `Return-path:' header is added to the message. RFC 822 states that the `Return-path:' header is `added by the final transport system that delivers the message to its recipient' (section 4.3.1), which implies that this header should not be present in incoming messages. Exim has a configuration option, `return_path_remove', which requests removal of this header from incoming messages, so that delivered messages can safely be resent to other recipients.
Option: suffix
Type: string
Default: "\n"
The string specified here is expanded and output at the end of every message.
The default is the same as for the `appendfile' transport.
It can be suppressed by setting
and this is usually necessary when doing batch SMTP deliveries.
suffix =
Option: timeout
Type: time
Default: 1h
If the command fails to complete within this time, it is killed. This normally causes the delivery to fail.
Option: umask
Type: integer
Default: 022
This specifies the umask setting for the subprocess that runs the command.
Option: use_crlf
Type: boolean
Default: false
This option causes lines to be terminated with the two-character CRLF sequence (carriage return, linefeed) instead of just a linefeed character. In the case of batched SMTP, the byte sequence written to the pipe is then an exact image of what would be sent down a real SMTP connection. If the `prefix' or `suffix' options are defined, their contents are written verbatim, so must contain their own carriage return characters if these are needed.
Option: use_shell
Type: boolean
Default: false
If this option is set, it causes the command to be passed to `/bin/sh' instead of being run directly from the transport as described in section "How the command is run". This is less secure, but is needed in some situations where the command is expected to be run under a shell and cannot easily be modified. The `allow_commands' and `restrict_to_path' options, and the `$pipe_addresses' facility are incompatible with `use_shell'. The command is expanded as a single string, and handed to `/bin/sh' as data for its `-c' option.
Option: user
Type: string
Default: unset
If this option is set, it specifies the user under whose uid the delivery process is to be run. If it is not set, a value must have been associated with the address by the director that handled it. If the string contains no $ characters, it is resolved when Exim starts up. Otherwise, the string is expanded at the time the transport is run, and must yield either a digit string or a name which can be looked up using `getpwnam()'. When `getpwnam()' is used, either at start-up time or later, the group id value associated with the user is taken as the value to be used if the `group' option is not set.
The `pipe' transport can be used to pass all messages that require local delivery to a separate local delivery agent such as `procmail'. When doing this, care must be taken to ensure that the pipe is run under an appropriate uid and gid. Typically one wants this to be a uid that is trusted by the delivery agent to supply the correct sender of the message. It may be necessary to recompile or reconfigure the delivery agent so that it trusts an appropriate user. The following is an example transport and director configuration for `procmail':
# transport procmail_pipe: driver = pipe command = "/opt/local/bin/procmail -d ${local_part}" from_hack user = exim # director procmail: driver = localuser transport = procmail_pipe
In this example, the pipe is run as the user `exim', assuming that `procmail' trusts that user. Note that the command that the pipe transport runs does not begin with
IFS=" "
as shown in the `procmail' documentation, because Exim does not by default use a shell to run pipe commands.
The next example shows a transport and a director for a system where local deliveries are handled by the Cyrus IMAP server.
# transport local_delivery_cyrus: driver = pipe command = "/usr/cyrus/bin/deliver \ -m ${substr_1:${$local_part_suffix}} -- ${local_part}" user = cyrus group = mail return_output log_output prefix = suffix =
# director local_user_cyrus: driver = localuser suffix = .* transport = local_delivery_cyrus
Note the unsetting of `prefix' and `suffix', and the use of `return_output' to cause any text written by Cyrus to be returned to the sender.
Go to the first, previous, next, last section, table of contents.