2011-09-11 81 views
0

我需要編寫一個perl腳本來發送電子郵件。 腳本應讀取包含電子郵件地址作爲其第一個參數的.txt文檔(可能有多個地址,它們全都用「;」分隔)和一個.html文檔,該文檔應該是電子郵件的主體郵件爲第二。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() 

所以我嘗試了一些東西,但是我在從.txt和.html文檔中提取信息時遇到了問題。所以這個錯誤應該是在收件人分裂的地方。

+0

檢查你的'$ to'變量。它是一個文件名,不是文件的第一行......另外,還有一些改進的指針:'use strict','open(my $ fh,'<','filename')'和'File :: Slurp'。 – Unk

+0

是的,我修正了這個問題,現在它可以工作,但是如果我在.txt文件中只留下一個電子郵件地址,否則它仍然沒有將它們分開。如果你只能幫助我 – Marin

回答

2

腳本中有幾個問題。我建議你使用Perl::Critic,因爲它會分析你的代碼,並且通常會提供有用的提示。

以下工作:

#!/usr/bin/env perl 

始終使用strictwarnings

use strict; 
use warnings; 

use Net::SMTP::SSL; 

English會給錯誤消息的文本表示

use English qw(-no_match_vars); 

Carp發出警告和錯誤的來電者的角度來看

use Carp; 

our $VERSION = '1.0.0'; 

sub send_mail { 

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

最好是有文件句柄作爲變量太多

my $to_handle; 
    my $text_handle; 

始終聲明變量

my @recipients; 
    my @lines; 

經常檢查系統調用的返回值(開,關,...)

# 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]'; 

我會避免在腳本源將密碼

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

    my $smtp; 

不要把新的生產線在模具/警告月底/ ...因爲它會刪除發生錯誤

行號
$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]; 

;分隔列表位於第一行(數組的第一個元素)中:您必須拆分第一行。

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

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

$subject沒有定義,你會用strictwarnings

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

這是一個很好的做法,結束子程序有回報的Perl檢測到使用最後的評價作爲的結果如果未指定返回,則返回結果。

return; 

} 

在主體中評估ARGV。如果將處理分散在一個或多個子程序中,您將失去清晰度

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

有一個缺少分號。您不需要使用&來調用子程序

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

1;