De acordo com as Leis 12.965/2014 e 13.709/2018, que regulam o uso da Internet e o tratamento de dados pessoais no Brasil, ao me inscrever na newsletter do portal DICAS-L, autorizo o envio de notificações por e-mail ou outros meios e declaro estar ciente e concordar com seus Termos de Uso e Política de Privacidade.
Colaboração: Rubens Queiroz de Almeida
Data de Publicação: 20 de dezembro de 2023
A tolerância com spam, muito acertadamente, é muito pequena.
Entretanto, existem problemas. Uma das técnicas para localizar spammers é semear pela Internet emails que não existem. Se você enviar uma mensagem para um destes endereços, então você está enviando emails não solicitados, ou spam.
O problema é que muito frequentemente endereços de email são descontinuados, e alguns provedores entendem, erroneamente, que ao enviar emails para estes endereços você está fazendo spam. Eu mesmo já tive um contrato cancelado por essa razão sem direito a acessar o servidor para fazer um backup. A minha sorte é que sempre mantenho várias cópias de meu trabalho e pude restaurar todo o conteúdo em outro provedor sem perder nada.
O que passei a fazer periodicamente foi a análise do log de emails para remover endereços que apresentavam algum tipo de problema.
Para isto uso um script bem simples:
grep -E "(not found|unknown user)" mail.log |\
sed 's/[ <>=:]/\n/g; s/[,()]//g' |\
sed -r '/@/!d; /dicas-l.com.br|MAILER-DAEMON/d' |\
sort -u > erros.txt
Vamos então entender o significado deste comando.
A expressão grep -E "(not found|unknown user)" mail.log busca, no
arquivo mail.log linhas que contenham as expressões not found ou
unknown user. A expressão not found está normalmente associada
a endereços de email cujos domínios não mais existem e a expressão
unknown user está associada a endereços de email que não são mais
válidos ou deixaram de existir.
A diretiva -E do grep permite que o grep interprete a expressão regular
como uma expressão regular estendida.
A segunda parte do comando, conectada por meio de um pipe (|),
sed 's/[ <>=:]/\n/g; s/[,()]//g' pega a saída do comando anterior e
realiza algumas substituições: os caracteres espaço em branco, <,
>, = e : são substituídos por uma quebra de linha e os caracteres
vírgula (,), abre e fecha parênteses (()) são apagados. A diretiva
-g do sed sinaliza que as substituições são feitas globalmente,
na linha inteira. Caso esta diretiva não fosse especificada, apenas a primeira
ocorrência de cada um dos caracteres listados anteriormente seria alterada.
A diretiva -r do sed permite o uso de expressões regulares estendidas.
Lembre-se, com o grep eu selecionei a linha inteira, mas eu estou
interessado apenas no email, então estas substituições se fazem
necessárias. Basta olhar o arquivo de log (mail.log) para compreender
a razão destas substituições:
Dec 20 16:22:42 Dicas-L postfix/local[121982]: 64ACCDE16E2: to=, relay=local, delay=0.24, delays=0.13/0/0/0.11, dsn=5.1.1, status=bounced (unknown user: "user")
Novamente, um pipe é usado para passar a saída do comando anterior para este sed.
A diretiva '/@/!d' deleta todas as linhas que não contêm o caractere
@, pois o que me interessa são apenas os endereços de email, e todos endereços de email
possuem o caractere @.
No arquivo mail.log eu encontro endereços de email cujo identificador
é MAILER-DAEMON e diversos outros emails de controle do domínio
dicas-l.com.br. Estes endereços não me interessam, pois são internos,
e a diretiva '/dicas-l.com.br|MAILER-DAEMON/d' deleta todas linhas que
contenham estas strings de texto.
Finalmente, preciso remover as linhas duplicadas, o que é feito com o comando
sort -u. A diretiva -u sinaliza ao comando sort que as linhas
duplicadas devem ser removidas do resultado final.
O resultado final será salvo no arquivo erros.txt.
O objetivo desta dica é demonstrar, com um exemplo prático, o uso do sed,
em combinação com outros comandos, em tarefas de processamento de logs e
análise de dados em sistemas Unix/Linux. Espero que estes conceitos lhe
sejam úteis.