2011-09-11 4 views
0

Je dois écrire un script Perl pour envoyer des emails. Le script doit lire le document .txt contenant les adresses de messagerie comme premier argument (il peut y avoir plus d'une adresse, et elles sont toutes séparées par ";") et un document .html qui devrait être le corps de l'e -mail comme son deuxième.script perl sendMail

#!/usr/bin/perl -w 
use Net::SMTP::SSL; 

sub send_mail { 

    my $to = $ARGV[0]; 
    open(MYFILE, $to) || die("Could not open file!"); 
    @recepients=<MYFILE>; 
    close(MYFILE); 

    my $body = $ARGV[1]; 
    open (TXTFILE, $body); 
    @lines = <TXTFILE>; 
    close(TXTFILE); 
    $body = join("",@lines); 

    my $from = '[email protected]'; 
    my $password = 'thePassword'; 

    my $smtp; 

    if (not $smtp = Net::SMTP::SSL->new('smtp.gmail.com', 
          Port => 465, 
          Debug => 1)) { 
     die "Could not connect to server\n"; 
    } 

    $smtp->auth($from, $password) || die "Authentication failed!\n"; 

    $smtp->mail($from . "\n"); 

    my @recepients = split(/;/, $to); 
    foreach my $recp (@recepients) { 
     $smtp->to($recp . "\n"); 
    } 
    $smtp->data(); 
    $smtp->datasend("From: " . $from . "\n"); 
    $smtp->datasend("To: " . $to . "\n"); 
    $smtp->datasend("Subject: " . $subject . "\n"); 
    $smtp->datasend("\n"); 
    $smtp->datasend($body . "\n"); 
    $smtp->dataend(); 
    $smtp->quit; 
} 

&send_mail() 

J'essayé de travailler quelque chose, mais j'ai un problème avec l'extraction des informations à la fois du txt et des documents .html. Donc l'erreur devrait être quelque part à la division des destinataires.

+0

Vérifiez votre variable '$ to'. C'est un nom de fichier, pas la première ligne du fichier ... De plus, quelques pointeurs vers l'amélioration: 'use strict',' open (mon $ fh, '<', 'nom de fichier') 'et' File :: Slurp'. – Unk

+0

ouais, j'ai corrigé ça, et maintenant ça marche, mais si je ne laisse qu'une adresse e-mail dans le fichier .txt, sinon ça ne les sépare pas. Si tu pouvais seulement m'aider avec ça – Marin

Répondre

2

Votre script comportait plusieurs problèmes. Je vous suggère d'utiliser Perl::Critic car il analyse votre code et donne généralement des conseils utiles.

Les travaux suivants:

#!/usr/bin/env perl 

Utilisez toujours strict et warnings

use strict; 
use warnings; 

use Net::SMTP::SSL; 

English donneront une représentation textuelle des messages d'erreur

use English qw(-no_match_vars); 

avertissements et erreurs de questions Carp de la perspective de l'appelant

use Carp; 

our $VERSION = '1.0.0'; 

sub send_mail { 

    my ($to, $body) = @_; 

il est préférable d'avoir des descripteurs de fichiers en tant que variables trop

my $to_handle; 
    my $text_handle; 

déclarent toujours les variables

my @recipients; 
    my @lines; 

Vérifiez toujours la valeur de retour des appels système (ouvrir, fermer , ...)

# print the error message in case of errors 
    open $to_handle, '<', $to 
     or croak "Error opening $to: $OS_ERROR"; 
    @recipients = <$to_handle>; 
    close $to_handle 
     or croak "Error closing $to: $OS_ERROR"; 

    open $text_handle, '<', $body 
     or croak "Error opening $body: $OS_ERROR"; 
    @lines = <$text_handle>; 
    close $text_handle 
     or croak "Error closing $body: $OS_ERROR"; 

    $body = join '', @lines; 

    my $from  = '[email protected]'; 

Je voudrais éviter de mettre un mot de passe dans la source de script

my $password = '*****'; 

    my $smtp; 

Ne pas mettre une nouvelle ligne à la fin de mourir/warn/... car il va supprimer le numéro de ligne où l'erreur est survenue

$smtp = Net::SMTP::SSL->new(
     'smtp.gmail.com', 
     Port => 465, 
     Debug => 1 
    ) or croak 'Could not connect to server'; 

    $smtp->auth($from, $password) 
     or croak 'Authentication failed!'; 

    $smtp->mail($from . "\n"); 

    # removed trailing \n 
    chomp $recipients[0]; 

La liste séparée ; est dans la première ligne (le premier élément de votre tableau): vous devez diviser la première ligne.

foreach my $recp (split /;/mxs, $recipients[0]) { 
     $smtp->to($recp . "\n"); 
    } 

    $smtp->data(); 
    $smtp->datasend("From: $from\n"); 
    $smtp->datasend("To: $to\n"); 

$subject n'a pas été défini, vous auriez détecté avec strict et warnings

$smtp->datasend("Subject: Test\n"); 
    $smtp->datasend("\n"); 
    $smtp->datasend("$body\n"); 
    $smtp->dataend(); 
    $smtp->quit; 

Il est une bonne pratique pour mettre fin à des sous-routines avec un retour en tant que Perl utilise le résultat de la dernière évaluation en tant que résultat si le retour n'est pas spécifié.

return; 

} 

Évaluez ARGV dans le corps principal.Vous perdrez clarté si vous dispersez le traitement dans un ou plusieurs sous-routines

if (!$ARGV[0] || !$ARGV[1]) { 
    print STDERR "usage: send to content\n"; 
    exit 1; 
} 

Il y avait un point-virgule manquant. Vous n'avez pas besoin d'utiliser & pour appeler des sous-programmes

send_mail ($ ARGV [0], $ ARGV 1);

1;