简体   繁体   English

perl脚本sendMail

[英]perl script sendMail

I need to write a perl script for sending emails. 我需要编写一个用于发送电子邮件的perl脚本。 The script should read .txt document containing the e-mail addresses as its first argument (there could be more than one address, and they are all separated with ";") and an .html document that should be the body of the e-mail as its second. 该脚本应该读取.txt文档,其中包含电子邮件地址作为其第一个参数(可能有多个地址,它们都用“;”分隔)和.html文档应该是e-的主体邮件作为第二个。

#!/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 = 'theAddress@gmail.com';
    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()

So I tried to work something out, but I have a problem with extracting the information both from the .txt and .html documents. 所以我试着解决一些问题,但是我从.txt和.html文档中提取信息时遇到了问题。 So the error should be somewhere at the splitting of the recipients. 所以错误应该是收件人分裂的某个地方。

There were several issues in your script. 您的脚本中存在多个问题。 I would suggest you to use Perl::Critic as it analyzes your code and usually gives helpful hints. 我建议您使用Perl :: Critic,因为它会分析您的代码,并且通常会提供有用的提示。

The following works: 以下作品:

#!/usr/bin/env perl

Always use strict and warnings 始终使用strictwarnings

use strict;
use warnings;

use Net::SMTP::SSL;

English will give a textual representation of error messages English将给出错误消息的文本表示

use English qw(-no_match_vars);

Carp issues warnings and error from the perspective of the caller Carp从调用者的角度发出警告和错误

use Carp;

our $VERSION = '1.0.0';

sub send_mail {

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

it is better to have filehandles as variables too 最好将文件句柄作为变量

    my $to_handle;
    my $text_handle;

Always declare variables 始终声明变量

    my @recipients;
    my @lines;

Always check the return value of system calls (open, close, ...) 始终检查系统调用的返回值(打开,关闭,...)

    # 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     = '.....@gmail.com';

I would avoid putting a password in the script source 我会避免在脚本源中输入密码

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

    my $smtp;

Don't put a new line at the end of die/warn/... as it will remove the line number where the error occurred 不要在die / warn / ...的末尾添加一个新行,因为它将删除发生错误的行号

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

The ; ; separated list is in the first line (the first element of your array): you have to split the first line. 分隔列表位于第一行(数组的第一个元素):您必须拆分第一行。

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

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

$subject was not defined, you would have detected it with strict and warnings $subject未定义,你会用strictwarnings检测到它

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

It is a good practice to end subroutines with a return as perl uses the result of the last evaluation as a result if return is not specified. 最好使用返回结束子例程,因为如果未指定return,perl将使用上一次求值的结果作为结果。

    return;

}

Evaluate ARGV in the main body. 评估主体中的ARGV You will loose clarity if you scatter the processing in one or several subroutines 如果将处理分散到一个或多个子例程中,则会松散清晰度

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

There was a missing semicolon. 有一个丢失的分号。 You don't need to use & to call subroutines 您不需要使用&来调用子例程

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

1;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM