command

<domain>

Какую программу запускать для писем этой очереди
в конфигурации это строкаcommandвнутри блока <domain>
Командная строка обработчика

Работает у очереди вида pipe (type) и для неё обязательна. Задаёт командную строку, которой узел запускает программу-обработчик; письмо подаётся ей на стандартный вход. Запуск происходит на каждого нового получателя.

В строке раскрываются подстановки со свойствами письма: $envid — идентификатор конверта, $user — имя получателя до собаки (а если в нём есть + — часть слева от него), $domain — его домен, $from и $to — адреса конверта, $isodate, $ctime, $rfctime, $timet — время в четырёх видах, $bodytype — вид тела письма.

Обратная косая черта удваивается. Она же служит для экранирования пробелов, кавычек и знака доллара, поэтому путь в стиле Windows пишется через двойные слэши — или через обычные прямые, их MTA тоже принимает.

Главная ловушка — подстановка без кавычек. Адрес получателя может содержать пробел, и тогда $user разъедется на несколько аргументов командной строки. Обработчик получит обрубок вместо адреса и обработает не то письмо. Руководство советует брать подстановки в двойные кавычки — совет стоит читать как требование.
Что делает Хаб. Не пишет: очередей вида pipe не заводит, разбор отказов у него свой и живёт в Хабе. В поставке PowerMTA есть две готовые программы — appendtofile и newfile, — если обработчик на узле всё-таки понадобится под простую задачу.
Рекомендуемые значения

Каждую подстановку — в двойные кавычки. Это единственная защита от пробела в адресе.

Программа должна стартовать быстро. Она запускается на каждого получателя; полсекунды старта при тысяче писем в минуту — это уже нагрузка на узел, а не на почту.

Путь пишите абсолютным. Узел запускает программу не из вашего окружения, и относительный путь работает не так, как в оболочке.

Требования про абсолютный путь и быстрый старт — наши. Из руководства здесь обязательность строки для вида pipe, полный список подстановок, удвоение обратной косой черты и совет брать подстановки в кавычки.
Пример в конфигурации
# обработчик отказов: идентификатор конверта и имя получателя
<domain bounces.example.com>
    type pipe
    command "/opt/bounce/parse --envid \"$envid\" \"$user\""</domain>
Кавычки внутри строки экранированы: сама строка тоже в кавычках, и без экранирования она оборвалась бы на первой из них.
жёлтым — — имена директив, голубым — блоки. Так же они подсвечены и в тексте карточки.
▲

Типичные ошибки и проблемы

что делают не так и чем это кончается3 ошибки▶

Пишут подстановки без кавычек

§ 3.3.10.111.1

Чем чреватоАдрес с пробелом разъезжается на несколько аргументов. Обработчик получает обрубок и обрабатывает не то письмо — молча, без ошибки.
Как заметитьИзредка обработчик срабатывает не по тому адресу, который стоял в конверте.
Как правильноВзять каждую подстановку в двойные кавычки, экранировав их внутри строки.

Задают относительный путь к программе

наш опыт

Чем чреватоУзел запускает программу не из вашего окружения. Путь, работающий в оболочке, здесь не находится, и письма стоят.
Как заметитьОчередь растёт, доставок ноль, в журнале ошибка запуска.
Как правильноПисать абсолютный путь и проверить права на запуск у пользователя, под которым работает служба.

Берут тяжёлый обработчик под поток

§ 11.21

Чем чреватоПрограмма запускается на каждого получателя. Обработчик, поднимающий интерпретатор или соединение с базой, при потоке съедает узел на одних запусках.
Как заметитьЗагрузка узла растёт вместе с очередью вида pipe.
Как правильноЛибо сделать обработчик лёгким, либо перейти на вид http-delivery — там процесс один и живёт постоянно.
Совместимость
PowerMTA 6.0
описана в руководстве этой версии · платформа: любая
С какой версии директива доступна, вендор указывает не для всех — здесь пометки нет. Имя встречается и в издании руководства 5.0.
Справочные данные
Синтаксис
command <string>
Значения
полная командная строка запуска программы в кавычках; допускаются подстановки $envid, $user, $domain, $from, $to, $isodate, $ctime, $rfctime, $timet, $bodytype
Применение
reload, перезапуск не нужен
Очередь
уже поставленное в очередь не затронет
Где писать
<domain>
Сколько раз
один раз в блоке
Всё здесь — из руководства, с разделом.
Наследование
Значение сливается по блокам <domain> от общего к частному: побеждает наиболее подходящий блок, а не последний по файлу. В очереди другого вида строка игнорируется — руководство говорит об этом про весь раздел pipe. Подхватывается по pmta reload; уже запущенные процессы обработчика доработают со старой строкой.
Как проверить на узле
Действующую строку печатает команда настроек очереди; работает ли обработчик — видно по тому, уходят ли из неё письма:
pmta show settings bounces.example.com/vmta1 | grep -E '^type|^command'
pmta show queues | grep -i bounces.example.com
Растущая очередь при заданной строке почти всегда означает, что программа не запускается: неверный путь или нет прав на запуск. Хаб очередей вида pipe не заводит.
В Хабе
Цена ошибки
опасно: последствия переживут откат
Сценарии
Подключить платформу отправки