Сценарий bash ищет:
12345 ; Serial
в каталоге / etc / bind / zone
. Он должен соответствовать любому числу перед ; Серийный
(с учетом регистра). И замените его форматом ГГГГММДДxx
.
#!/bin/bash
ZONES_PATH="/etc/bind/zones"
DATE=$(date +%Y%m%d)
# we're searching for line containing this comment
NEEDLE="Serial"
for ZONE in $(ls -1 $ZONES_PATH) ; do
curr=$(/bin/grep -e "${NEEDLE}$" $ZONES_PATH/${ZONE} | /bin/sed -n "s/^\s*\([0-9]*\)\s*;\s*${NEEDLE}\s*/\1/p")
# replace if current date is shorter (possibly using different format)
if [ ${#curr} -lt ${#DATE} ]; then
serial="${DATE}00"
else
prefix=${curr::-2}
if [ "$DATE" -eq "$prefix" ]; then # same day
num=${curr: -2} # last two digits from serial number
num=$((10#$num + 1)) # force decimal representation, increment
serial="${DATE}$(printf '%02d' $num )" # format for 2 digits
else
serial="${DATE}00" # just update date
fi
fi
/bin/sed -i -e "s/^\(\s*\)[0-9]\{0,\}\(\s*;\s*${NEEDLE}\)$/\1${serial}\2/" ${ZONES_PATH}/${ZONE}
echo "${ZONE}: "
grep "; ${NEEDLE}$" $ZONES_PATH/${ZONE}
done
Измененная версия для конфигурации привязки, управляемая в репозитории git
, которая обновляет серийный номер только для измененного файла зоны:
#!/bin/bash
ZONES_PATH="$(pwd)/zones"
REPO_PATH="$(git rev-parse --show-toplevel)"
DATE=$(date +%Y%m%d)
NEEDLE="Serial"
for ZONE in $(git diff --name-only --diff-filter=AM `git merge-base origin/master HEAD` $ZONES_PATH) ; do
curr=$(/bin/grep -e "${NEEDLE}$" ${REPO_PATH}/${ZONE} | /bin/sed -n "s/^\s*\([0-9]*\)\s*;\s*${NEEDLE}\s*/\1/p")
if [ ${#curr} -lt ${#DATE} ]; then
serial="${DATE}00"
else
prefix=${curr::-2}
if [ "$DATE" -eq "$prefix" ]; then # same day
num=${curr: -2} # last two digits from serial number
num=$((10#$num + 1)) # force decimal representation, increment
serial="${DATE}$(printf '%02d' $num )" # format for 2 digits
else
serial="${DATE}00" # just update date
fi
fi
/bin/sed -i -e "s/^\(\s*\)[0-9]\{0,\}\(\s*;\s*${NEEDLE}\)$/\1${serial}\2/" ${REPO_PATH}/${ZONE}
echo "${ZONE}: "
grep "; ${NEEDLE}$" ${REPO_PATH}/${ZONE}
done
Примечание: вы не должны вносить более 99 изменений в течение одного дня: )
Оказывается, мой ответ был в обширной документации getmail. Мне нужно использовать то, что getmail вызывает MultiGuesser
.
Однако, поскольку в моем случае мой интернет-провайдер добавлял подобную строку в заголовки конвертов:
for <xxx@DOMAIN.com>
и поскольку MultiGuesser не совершенен (, например. он не может правильно угадать, если получатель скрыт )Наконец-то я реализовал первоначальную идею добавления delivered_to
строк. Я сохранил MultiGuesser на тот случай, если мой интернет-провайдер перестанет добавлять эту полезную строку. Утилита представляет собой bash-скрипт, использующий formail
(, предложенный dirkt в его ответе ). Это не быстро, потому что создает временные файлы для каждой обрабатываемой почты, но работает нормально.
#!/bin/bash
# Reads email from stdin and prints it to stdout with a twist:
# If it finds a line like " for <xxx@yyyy.zz>" in the envelope
# it will assume it refers to the receipient and will add a "Delivered-To"
# envelope line that will make getmail happy. -- Nick Demou 2018
# bash options for safety in case of errors
set -euf -o pipefail
# read stdin to temp file
cat - > /tmp/deliver.to.$$
logger -p mail.info "getmail, filtering via temp file /tmp/deliver.to.$$"
formail -X "" < /tmp/deliver.to.$$ > /tmp/deliver.to.$$.env
# logger -p mail.info "getmail, extracted envelope/headers to /tmp/deliver.to.$$.env"
ID=`grep 'SMTP id ' /tmp/deliver.to.$$.env 2>/dev/null| head -1|sed -e 's/^ *//'` || ID=UNKNOWN
# logger -p mail.info "getmail, extracted ID $ID"
ADDR=`grep '^ *for <.*@domain\.com>' /tmp/deliver.to.$$.env 2>/dev/null|head -1|sed -e 's/^.*<\([^>]*\)>.*$/\1/'` || ADDR=UNKNOWN
# logger -p mail.info "getmail, extracted delivery address $ADDR"
if echo $ADDR | grep -q '^[^@]*@domain.com *$' ; then
cat /tmp/deliver.to.$$ | formail -A "Delivered-To: $ADDR"
else
cat /tmp/deliver.to.$$
fi
logger -p mail.info "getmail filtered mail for $ADDR, $ID"
rm /tmp/deliver.to.$$
rm /tmp/deliver.to.$$.env
Мой getmailrc
содержит подобный фильтр, который вызывает приведенный выше скрипт:
[filter-1]
type = Filter_external
path = /opt/envelope-add-delivered-to.sh
Если "утилита" означает "скрипты оболочки для отправителя/получателя", взгляните на formail . Для автоматической обработки полученной почты на основе -пользователя посмотрите procmail .
Если вы заменяете сервер обмена почтовым сервером Linux, вы, вероятно, захотите сделать это каким-то образом внутри сервера.