Todo mundo fica dizendo que e-mail é coisa do passado e que o futuro mesmo é utilizar as redes sociais e a Web 2.0 (lol) para se comunicar. Mas a verdade é que o e-mail ainda é muito útil e acredito que vai demorar bastante tempo para que isso mude. No pior dos casos, e-mail ainda continua sendo uma boa forma de registro e notificação.
E no caso da notificação, enviar e-mail via linha de comando do Linux é bastante útil. Terminou uma tarefa no crontab? Envia um e-mail com o resultado. Caiu um servidor? Envia um e-mail para alguém notificando. Ou então querer apenas testar um servidor de e-mail local? É só usar a imaginação.
Como todos sabemos, o Linux conta com o recurso de shell, que por sua vez permite criar poderosos programas que são chamados de shell scripts. Vejamos aqui esta pequena dica de como enviar e-mail via linha de comando.
O comando mail
O comando mail será usado aqui primeiramente. Ele está contido no pacote mailx, geralmente em todas as distribuições (Debian por exemplo, é o bsd-mailx, Red Hat/Fedora seria apenas mailx). Além disso, é necessário um servidor de e-mail local, o que é comum em todas as distribuições Linux por aí.
Mandando um e-mail com o comando mail, manualmente, via linha de comando:
mail -s "Assunto Teste" [email protected]
O parâmetro -s especifica o assunto da mensagem. Coloque entre aspas como no exemplo para que ele reconheça todo o assunto com espaços. O último argumento é o endereço para quem se vai enviar a mensagem.
Quando você der ENTER, não vai aparecer nada e nem vai voltar pro prompt. Digite então toda a sua mensagem e quando terminar, aperte CTRL+D. Vai aparecer um “Cc:“, que significa que se você quiser enviar cópia para alguém, basta colocar agora. Aperte ENTER e vói-lá! A mensagem foi para o destinatário (bem, pelo menos era pra ir!).
Agora vamos utilizar um modo mais rápido e não-interativo de se mandar o mesmo e-mail:
echo "Isto é um e-mail de teste" | mail -s "Assunto Teste 2" [email protected]
Agora ao invés de você ter que digitar, ele já joga a mensagem “Isto é um e-mail de teste” no corpo e manda o e-mail. Isso serve para você acoplar justamente em um shell script sem ter que precisar que alguém digite alguma coisa na hora.
Mas o echo ainda é limitado para mensagens grandes, então vamos ler de um arquivo:
mail -s "Assunto Teste 3" [email protected] < /var/log/syslog
Ele usou um redirecionador (mais sobre eles no artigo Shell: Entrada e Saída) para que o conteúdo do arquivo /var/log/syslog se tornasse o corpo da mensagem. Mais uma vez, você pode usar um shell-script para gerar o arquivo com o conteúdo que você quiser e depois mandar por e-mail.
Há outros parâmetros no comando mail também. Para ver todos, basta ler a boa e velha página de manual (man mail).
Outro exemplo:
echo 'Maravilha!' | mail -s "Assunto Teste 4" [email protected] \ -c [email protected],[email protected] \ -b [email protected]
Neste caso, mandei um e-mail para [email protected], com cópia para [email protected] e [email protected] (vários e-mails separados por vírgula) e uma cópia oculta para [email protected].
O comando mail faz parte do sistema padrão de e-mails locais que é utilizado há vários anos pelos sistemas Unix em geral. Por isso, o campo From, ou seja, o Remetente da mensagem vai ser o usuário que está executando o comando, mais o nome completo da máquina. Exemplo, se eu sou o usuário eitch, na máquina batima.devin.com.br, quer dizer que o Remetente será: [email protected].
Anexos com o mutt
Como nem tudo são flores, na hora de mandar arquivos anexos junto a mensagem, o comando mail não suporta essa funcionalidade. Neste caso, geralmente o pessoal utiliza o cliente de e-mail de linha de comando mutt.
O mutt é na verdade um cliente de e-mail para linha de comando completo. Pode ser que sua distribuição Linux não tenha esse programa instalado. Então se o comando mutt não for encontrado, instale o programa junto à sua distribuição (com o apt-get, yum, ou outros).
O comando é bem parecido com o do mail:
echo "Assunto Anexo" | mutt -s "Assunto Teste 5" -a arquivo.zip [email protected]
O parâmetro -a é quem cuida dos anexos. No caso de enviar vários anexos, é necessário também que o -a fique antes do destinatário, seguido por “–“, assim:
echo "Assunto Anexo" | mutt -s "Assunto Teste 6" \ -a /home/eitch/imagem.jpg /var/log/syslog /home/eitch/arquivo.zip -- [email protected]
Via um servidor SMTP
Não são todos os sistemas que tem um servidor de e-mail local. Por exemplo, algumas máquinas de hostings não possuem um sendmail, postfix ou qmail instalados e prontos para usar. Em outros casos, organizações preferem ficar sem o servidor de e-mail de cada máquina e concentrar tudo em uma única file de e-mail, um único servidor de e-mail na rede. Este caso do servidor de e-mail único é bem comum.
O SMTP – Simple Mail Transfer Protocol é o protocolo para envio de e-mails e um servidor SMTP é justamente o que recebe os e-mails e repassa para outros servidores necessários. Não vou me aprofundar muito no assunto SMTP, mas vamos aprender um pouco como usá-lo diretamente.
Para fazer essa parte, você precisa ter um servidor STMP já funcionando. Neste tutorial, usaremos como exemplo o smtp.devin.com.br, que é fictício. Substitua este servidor pelo seu.
Pra enviar o e-mail, vamos primeiro conversar diretamente com o servidor SMTP através do comando nc. O nc é o comando netcat e serve para abrir conexões TCP puras e transferir dados para ela (como se fosse um telnet não-interativo). Se o comando nc não existir na sua máquina, instale-o dos repositórios, já que vem em praticamente todas as distribuições Linux.
Exemplo de script shell para mandar e-mail via nc:
#!/bin/bash # cat <<EOF | /usr/bin/nc smtp.devin.com.br 25 HELO $(hostname) MAIL FROM: <[email protected]> RCPT TO: <[email protected]> DATA From: Hugo Cisneiros (Eitch) <[email protected]> To: Nome do Destino <[email protected]> Date: $(date '+%a, %d %b %Y %H:%M:%S %z') Subject: Assunto da mensagem Content-Type: text/plain; charset=UTF-8 Fala Destinatário! Estou mandando este e-mail via shell script, usando o nc diretamente pelo SMTP. Legal né? Abraços! . QUIT EOF
O que fizemos no exemplo é conversar usando o protocolo SMTP.
- Na linha 3 usamos o comando cat para capturar tudo o que digitarmos, até haver uma linha EOF (End Of File). Pense nisso como se fosse um comando echoextendido. Depois repassamos todo esse texto via pipe para o comando nc smtp.devin.com.br 25, que conecta ao servidor SMTP na porta 25. Para aprender mais sobre o pipe veja o Shell: Entrada e Saída;
- A linha 4 identifica quem é você. O comando hostname identifica-o com o nome da sua máquina;
- As linhas 5-6 contém de quem é o e-mail (MAIL FROM) e qual o destino (RCPT TO);
- A linha 7, com o comando DATA, especifica que tudo que tiver a partir da próxima linha serão os dados do e-mail. Estes dados terminam quando houver uma linha apenas com o caracter ponto (.), que vai significar que o e-email acabou e pode ser mandado;
- As linhas 8-12 contém o cabeçalho do e-mail. Cada cabeçalho é uma linha. No exemplo temos o nome da pessoa que enviou, do destinatário, a data atual (gerada automaticamente pelo comando date), o assunto (Subject) da mensagem e a codificação da mensagem (para a acentuação do português) não sair estranha. Os cabeçalhos acabam quando uma linha em branco é recebida;
- As linhas 14-20 são o corpo da mensagem. Engloba tudo depois da linha em branco que finaliza o cabeçalho, até o caracter ponto que termina o e-mail.
- A linha 21, já falada, termina o e-mail. Ao receber o ponto, o servidor SMTP já coloca a mensagem na fila para o envio. A partir daí você pode enviar outro e-mail (começando com o MAIL FROM), ou sair, como na próxima linha com o comando QUIT.
- Na última linha, o EOF avisa ao cat que acabou o texto e o manda para o comando nc, como diz a linha 3.
Até que é fácil né? Basta agora ir substituindo os campos de e-mail e testando. Esse método com o comando nc é o ideal para utilizar junto com shell-scripts em servidores. Ele só não serve muito bem para mandar anexos, pois transformar os anexos para mandar via nc não é algo trivial de se fazer.
Referências
- RFC 2821 – Simple Mail Transfer Protocol
- man 1 mail
- man 1 mutt