Окей пикабу!
Так как мой предыдущий пост разнесли в пух и прах (вполне заслуженно), я насуплю ещё раз на эти грабли. Но не для получения по голове, а во имя развития и обучения. Как моего персонально, так и всех в общем. Итак.
Есть задача: очистить всю почтовую очередь по шаблону. Какой шаблон - дело ваше. Или удалить весёлое общение двух автоответчиков, или убрать отчёты о недоставленных письмах или просто ради хохмы (что должно караться тапком по загривку). То есть причины мы опустим. Приступим к реализации.
Учтя предыдущи печальный опыт, я добавил комменты в код.
#!/bin/bash
###############################
# Set Default value #
###############################
date_s=$(date +%s)
printf "Starts at %s %s\n" `date '+%Y/%m/%d %H:%M:%S'`
###############################
# Get messages by pattern #
###############################
# if parameter exists
if [[ -n "$1" ]];
then
# 1) Get queue as JSON string
# 2) Get messages by pattern
# 3-5) Remove garbage
# 6) Loop
postqueue -j | grep -i "$1" | sed "s/\":[\ \"\[\{]*/:/g" | sed -e "s/\",\ \"/\ /g" -e "s/,\ \"/\ /g" | sed "s/recipients\://g" | while read msg
do
recipients=""
for item in ${msg:2:-4};
do
case "$item" in
queue_id\:*) id=${item#*\:} ;;
sender\:*) sender=${item#*\:} ;;
address\:*) recipients=`printf "%s %s" $recipients ${item#*\:}` ;;
esac
done
# Remove garbage from "id" value
id=`printf $id | sed "s/[\@\*]//g"`
printf "Delete meessage (ID=%s): from %s to %s\n" $id $sender $recipients
postsuper -d $id
done
fi
###############################
# Get relayed messages #
###############################
postqueue -j | grep -viE "server1.com|server2.ru" | sed "s/\":[\ \"\[\{]*/:/g" | sed -e "s/\",\ \"/\ /g" -e "s/,\ \"/\ /g" | sed "s/recipients\://g" | while read msg
do
recipients=""
for item in ${msg:2:-4};
do
case "$item" in
queue_id\:*) id=${item#*\:} ;;
sender\:*) sender=${item#*\:} ;;
address\:*) recipients=`printf "%s %s" $recipients ${item#*\:}` ;;
esac
done
id=`printf $id | sed "s/[\@\*]//g"`
printf "Delete meessage (ID=%s): from %s to %s\n" $id $sender $recipients
postsuper -d $id
done
###############################
# Finish #
###############################
printf "Ends at %s %s\n" `date '+%Y/%m/%d %H:%M:%S'`
let "date_r = `(date +%s)` - date_s"
printf "Runtime: %s %s\n" `date -u -r $date_r +%T`
Что делает скрипт?
1) Подготовка. Вывожу время запуска и запоминаю его (в секундах)
2) Если есть параметр, то начинаю искать.
3) В любом случае ищу сообщения, не имеющие отношение к моим серверам (например, server1.com и server2.ru). Сделал просто так... Для примера... Кто в себе уверен - удаляйте.
4) Вывожу время окончание и время работы.
Как происходит поиск?
Я воспользовался выводом postqueue в формате JSON. Почему именно так? потому что результат возвращается в одну (!) строчку за сообщение и я легко могу найти любое "попадание" по шаблону.
Так, как формат JSON древовидный, то приходится очищать вывод от разных символов: всяческие скобки, запятые и подгонять под удобные для обработки формат.
После получения мега-форматированных строк ( в которых есть символы переноса строки) я их перебираю, и, благодаря case-у вытаскиваю нужное мне. За один проход. После - вывод необходимой информации (по вкусу. можно закомментить, но тогда и скрипт был бы проще =)).
При вызове указать параметр (адресант, адресат или текст сообщения(??)). Либо ничего не указывать. =) Конечно же, запуск от имени root и иже с ним, так как postsuper требует повышения прав.
К тухлым помидорам морально готов =(.
P.S. Скрипт отчасти на коленке. То есть: очередь находит корректно, удалять мне (к счастью) пока нечего. Да и в куске
id=`printf $id | sed "s/[\@\*]//g"`
может быть затык. Добавил этот костыль, так как помню, что в очереди могут быть сообщения, начинающиеся с символов @ и *