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 часа. Пока что не выявлял где можно выиграть время, но если подскажите или укажите на ошибки — буду благодарен.

Спасибо за прочтение и коментарии.

ссылка на оригинал статьи https://habrahabr.ru/post/277117/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *