Вот немного улучшенная версия вашего скрипта. Он использует $ (pwd)
, а не обратные тики, одинарные кавычки вокруг литеральных строк (адреса From и To, а также строку темы), двойные кавычки, где требуется интерполяция переменных, и использует heredoc для заголовков, а не для нескольких строк echo
. Мне нравится использовать строку __ EOF __
для разграничения heredoc, потому что она вряд ли встречается в теле heredoc ... любая произвольная строка также будет работать.
Обратите внимание на последнюю пустую строку перед концом heredoc - пустая строка требуется для разделения заголовков и тела сообщения.
Кстати, переменные интерполируются внутри heredocs таким же образом, как и для строк в двойных кавычках. Вы даже можете использовать в них подстановку команд $ (...)
.
#! /bin/sh
DOCROOT=$(pwd)
$header="$DOCROOT/header.txt"
$body="$DOCROOT/report.html"
MAIL_FROM='donotreply@mydom.com'
MAIL_TO='myname@mydom.com'
$subject='The mail subject'
cat <<__EOF__ > "$header"
From: $MAIL_FROM
To: $MAIL_TO
Subject: $subject
Content-Type: text/html
__EOF__
cat "$header" "$body" | /usr/lib/sendmail -t
Сообщите мне, если это решит вашу проблему.
Кстати, чтобы ответить на ваш реальный вопрос, sendmail
должен регистрироваться везде, где в вашей системе отправляется электронная почта - возможно, /var/log/mail.log
или подобное, попробуйте grep mail /etc/syslog.conf
, чтобы проверить это.
Мониторинг журнала в реальном времени с использованием подстановки процесса bash:
#!/bin/bash
while IFS='$\n' read -r line;
do
# action here, log line in $line
done < <(tail -n 0 -f /var/log/apache2/other_vhosts_access.log | \
grep '/somefile.pdf?utm_source=email392')
Подстановка процессапередает в цикл чтения выходные данные из конвейера внутри <(...)
. Сама строка лога присваивается переменной $line
.
Журналы просматриваются с помощью tail -f
, который выводит строки по мере их записи в журналы. Если ваши файлы журнала периодически перемещаются с помощью logrotate , добавьте параметры --follow=name
и --retry
, чтобы отслеживать путь к файлу, а не только дескриптор файла.
Вывод из хвоста направляется в grep
, который фильтрует соответствующие строки, соответствующие вашим URL-адресам.
Можно взять вот такой один лайнер:
grep -q "utm_source=email392" /var/log/apache2/other_vhosts_access.log && grep -q "utm_source=email392" /var/log/apache2/other_vhosts_access.log | mail -S "Accessed!" foo@bar.com
и периодически запускайте его через cron
.
Объясняя это более подробно :первый grep
используется только для проверки необходимости дальнейших действий (добавление -q
делает его тихим, скрывая любые совпадения, которые он может найти ). &&
означает, что остальная часть строки будет выполняться только в том случае, если первая grep
найдет совпадение (, т.е. вернет 0 ). Если это так, совпадающая строка (с ), полученная вторым grep
, передается в mail
для отправки foo@bar.com
по электронной почте с темой, указанной аргументом -s
. (" Доступ! " ).
Та же логика(grep -q... &&...
)может использоваться для выполнения любых других действий. Вы можете запускать все, что хотите, после &&
, например. сценарий оболочки для более сложных вещей.
Обратите внимание, что если вы запускаете это с более высокой частотой, чем частота вращения журнала --, например. проверка ежечасно, но ротация журналов ежедневно --действие может запускаться несколько раз, так как grep
будет находить одну и ту же строку (с )снова и снова, пока журнал не будет ротироваться.
Пока я писал свое решение, я обнаружил, что первый ответ похож на мой. В этом случае я бы порекомендовал также избегать crontab. Я опубликую свой код.
#!/bin/bash
file="$1"
pattern="$2"
tail -f -n0 $file | {
while IFS= read -r line
do
if [ ! -z $(echo $line | grep "$pattern") ] ; then
echo "visited $pattern" | mail user@example.com
fi
done
}
Кроме того, вы можете запустить его в фоновом режиме с помощью оператора &
:
./checklog.sh /var/log/apache2/other_vhosts_access.log "somefile.pdf?utm_source=email392" &
или запустить его как «демон» при загрузке системы
Попробуйте fail2ban с фильтром apache -badbots.conf, (замените регулярное выражение на ваш URL )и как действие sendmail.conf
[mycustombot]
enable = true
filter = apache-badbots ##your "custom" script
action = sendmail[name=MyBadBot,dest=youremail@be.happy]
logpath = /your/access/logs/*/path
Публикую то, что я, наконец, использую, для дальнейшего использования (хорошо, я знаю, что один вкладыш иногда бывает плохим, но...):
tail -F -n0 /var/log/apache2/other_vhosts_access.log | grep --line-buffered "?src=_" | { while IFS= read -r line; do echo "$line" | mail test@example.com; done } &
Примечания:
Я должен использовать grep --line-buffered
из-за этого .
tail -F
, кажется, заменяет --follow=name --retry
, как упоминалось здесь .
(Конечно, заслуга Себаста и Вакса.)
это можно сделать с помощью rsyslog и модуля ommail
http://www.rsyslog.com/doc/v8-stable/configuration/modules/ommail.html
что-то вроде:
module(load="ommail")
if $msg contains "/somefile.pdf?utm_source=email392" then {
action(type="ommail" server="..." port=".."
mailfrom="...."
mailto="..."
subject.text="Page Viewed!")
}
это будет работать, если apache настроен на ведение журнала с использованием системного журнала