[Из песочницы] Zimbra: удаление случайных или ненужных писем
Тема, возможно, избита и не очень актуальна, если настроено автоматическое удаление писем по истечению определенного срока.
Но если случается, что один сотрудник вместо того, чтобы отправить очень приватно-пикантное сообщение другому, отправляет его (сообщение) всему холдингу… Ждать день, когда стартанет автоматическая очистка — не вариант, а удалить надо сейчас и у всех.
Под катом описание того, как это реализовано у меня.
Покопавшись в сети, наткнулся на сайт, где описан небольшой скрипт для удаления старой почты, он не плох, но не подходил для удаления писем в подпапках.
Проблемы решал по-мере приближения к основной задаче.
Для начала нужно найти все папки, в которые могло попасть письмо с подробностями вечера, для этого нам поможет zmmailbox (мощный и всеобъемлющий помошник). Вводим:
/opt/zimbra/bin/zmmailbox -z -m user@corp.org gaf # gaf - getAllFolders
В ответ получаем:
Id View Unread Msg Count Path
---------- ---- ---------- ---------- ----------
1 unkn 0 0 /
16 docu 0 15 /Briefcase
10 appo 0 52 /Calendar
14 mess 0 1564 /Chats
7 cont 0 7 /Contacts
6 mess 0 56 /Drafts
13 cont 0 179 /Emailed Contacts
2 mess 0 5352 /Inbox
65450 mess 0 12433 /Inbox/до 1.04.2015
31907 mess 0 3125 /Inbox/Маркетинг
5993 mess 0 881 /Inbox/Юрики
4 mess 0 0 /Junk
5 mess 0 7527 /Sent
15 task 0 8 /Tasks
3 unkn 0 0 /Trash
1770 mess 7 7 /Trash/Тех. Поддержка (support@corp.org:703)
3741 docu 0 1 /Инструкция
87195 docu 0 1 /Коменты
1015 docu 0 12 /Личный
663 cont 0 1 /ОБЩАЯ АДРЕСНАЯ КНИГА
290 task 0 2 /Общедоступные
1100 mess 4404 22301 /Тех. Поддержка - Входящие (support@corp.org:2)
Как видим, у нас полным-полно всего. Столбец View нам предподоткрывает глаза и мы видим, что там типы папок. Нам нужны папки с сообщений — это mess. Зная что нам нужно, можем отфильтровать запрос:
/opt/zimbra/bin/zmmailbox -z -m user@corp.org gaf | grep mess
Вывод запроса:
Id View Unread Msg Count Path
---------- ---- ---------- ---------- ----------
14 mess 0 1564 /Chats
6 mess 0 56 /Drafts
2 mess 0 5352 /Inbox
65450 mess 0 12433 /Inbox/до 1.04.2015
31907 mess 0 3125 /Inbox/Маркетинг
5993 mess 0 881 /Inbox/Юрики
4 mess 0 0 /Junk
5 mess 0 7527 /Sent
1770 mess 7 7 /Trash/Тех. Поддержка (support@corp.org:703)
1100 mess 4404 22301 /Тех. Поддержка - Входящие (support@corp.org:2)
Как видим, получаем уже более нужный список, но 1100 mess 4404 22301 /Тех. Поддержка — Входящие (support@corp.org:2) — это расшаренная папка с другого ящика, а, следовательно, она будет проверена отдельно. Добавим еще одно исключение и сразу уберем все лишнее: типы, порядковые номера, уберем все до слеша (названия папок).
/opt/zimbra/bin/zmmailbox -z -m user@corp.org gaf | grep mess | cut -d"/" -f 2- | grep -v "@corp.org"
Получаем нужный список:
Chats
Drafts
Inbox
Inbox/до 1.04.2015
Inbox/Маркетинг
Inbox/Юрики
Junk
Sent
Вывод команды перенаправляю в файл, для небольшого и редкого удобства, и уже из файла скрипт будет брать названия папок. Итак, самое сложное — это не столько заглядывать в папки, сколько заглядывать в папки, имена которых содержат пробелы или спецсимволы.
Если ввести в консоли:
/opt/zimbra/bin/zmmailbox -z -m user@corp.org s -l 300 in:Inbox/Папка | grep `date -d '-5 day' +%m/%d/%y` | grep "Вечеринка" | sed -e "s/^\s\s*//" | sed -e "s/\s\s*/ /g"
Выводит темы писем 5-ти дневной давности. Вместо date -d '-5 day' +%m/%d/%y можно сразу писать даты в фомате 01/27/16 или меняя -5 на другое значение, в зависимости от того, на сколько дней назад надо откатиться.
Но если ввести:
/opt/zimbra/bin/zmmailbox -z -m user@corp.org s -l 300 in:Inbox/Папка Секретов | grep `date -d '-5 day' +%m/%d/%y` | grep "Вечеринка" | sed -e "s/^\s\s*//" | sed -e "s/\s\s*/ /g"
То вывалится ошибка:
ERROR: mail.NO_SUCH_FOLDER (no such folder path: /Inbox/Папка\)
И хоть обвставляйся кавычками, апострофами и экранами — не поможет.
Тут мне указали на вики, в которой нашел ответ на вопрос.
Для решения проблемы нужно поместить в определенные блоки имя папки с пробелами. »\» — вот блоко-тег.
/opt/zimbra/bin/zmmailbox -z -m user@corp.org s -l 300 in:"\"Inbox/Папка Секретов"\"
Выполнив это в консили, получил требуемый результат, но моя задача состояла все скриптозовать. И в моем скрипте переменная, содержащая название папки, брала данные из файла.
/opt/zimbra/bin/zmmailbox -z -m user@corp.org gaf | grep mess | cut -d"/" -f 2- | grep -v "@corp.org" > /tmp/messfolder.list
И при вставлении переменной в мой код:
/opt/zimbra/bin/zmmailbox -z -m $i s -l 300 in:"\"$p"\" | grep `date -d '-5 day' +%m/%d/%y` | grep "Вечеринка" | sed -e "s/^\s\s*//" | sed -e "s/\s\s*/ /g" |
У меня вываливалась таже ошибка:
ERROR: mail.NO_SUCH_FOLDER (no such folder path: /Inbox/Папка\)
Хотя переменная и помещена в нужные блоко-теги. Поискав еще немного, вспомнил наткнулся на переменную разделителя поля IFS. Задал ему значение IFS=$'\n' и запустил скрипт — все пошло как и планировалось.
#!/bin/bash
DOMAIN_NAME="corp.org" # Тут домен
EMAIL=/tmp/email.list # Это список всем ящиков
MESID=/tmp/mesid.list # это ID писем для удаления
DELTEXT='вечеринка' # Слово в теме письма или сама тема письма
IFS=$'\n' # Переменная отвечающая за разделитель поля
before="$(date +%s)" # Время запуска скрипта
t=0 # Переменная, для подсчета удаленных писем
/opt/zimbra/bin/zmprov -l gaa $DOMAIN_NAME | sort > $EMAIL # Собираем список ящиков
# Ну и циклом их перебираем
for i in $(cat $EMAIL);
do
echo $i
# Тут мы получаем список всех папок, отсеим папки которые расшаренные, так как они и так будут пройдены и исключаем папки, которые не почтовые - это Портфель, и Контакты и прочие, не mess
/opt/zimbra/bin/zmmailbox -z -m $i gaf | grep mess | cut -d"/" -f 2- | grep -v "@corp.org" > /tmp/messfolder.list
# Теперь циклом проходим по списку и получаем название папки, затем всталяем в запрос и получаем id сообщения для удаления. И так проделываем с каждой папкой.
for p in $(cat /tmp/messfolder.list);
do
echo $p
# Тут все просто: до первого grep мы выводим сообщения из ящика, grep фильтрует по дате, второй grep по теме, затем sed'ы убирают лишние пробелы и cut вырезает остаток и получаем чистый, фильтрованный номер сообщения.
/opt/zimbra/bin/zmmailbox -z -m $i s -l 300 in:"\"$p"\" | grep `date -d '-5 day' +%m/%d/%y` | grep "$DELTEXT" | sed -e "s/^\s\s*//" | sed -e "s/\s\s*/ /g" | cut -d" " -f2 > $MESID
# Выводим номер сообщения и считаем кол-во сообщений.
cat $MESID
count=`grep '' $MESID -c`
let t=$t+$count
for a in $(cat $MESID | grep ^- | sed s/-//g )
do
/opt/zimbra/bin/zmmailbox -z -m $i deleteMessage $a
done
for a in $(cat $MESID | sed /-/d)
do
/opt/zimbra/bin/zmmailbox -z -m $i deleteConversation $a
done
echo -n > $MESID
RES=$?
if [ "$RES" == "0" ]; then echo "[Ok]"; else echo "[Err]"; fi
done
echo "Найдено писем: "$t
done
after="$(date +%s)"
elapsed="$(expr $after - $before)"
hours=$(($elapsed / 3600))
elapsed=$(($elapsed - $hours * 3600))
minutes=$(($elapsed / 60))
seconds=$(($elapsed - $minutes * 60))
echo "Скрипт выполнялся: $hours часов $minutes минут $seconds секунд"
echo "Всего удалено: "$t" писем"
Конечно, скрипт можно еще доработать: убрать ненужные папки, вводить дату и тему заранее, но это уже не так принципиально. Этот скрипт повесил на самодельную веб-админку и все даты и темы для удаления ввожу из нее, все ж удобнее.
Кто-то посчитает, что это лишнее, и такой скрипт излишен, но как показала практика — он спас как минимум 10 человек и пару начальников. Им хорошо, и админу после того, как им стало хорошо, тоже стало хорошо.
У этого скрипта есть один минус — это время. Данный скрипт пробегает по всем папкам 700 пользователей за 4 часа. Пока что не выявлял где можно выиграть время, но если подскажите или укажите на ошибки — буду благодарен.
Спасибо за прочтение и коментарии.