我正在处理一个执行很多事情的脚本,并且如果在执行过程中的任何时刻执行了“死亡”或发生了错误,我想向自己发送一封电子邮件。如果在Perl脚本中发生错误,发送电子邮件的最佳方式是什么?
我正在使用END块来检查退出状态,如果它大于0,则调用一个错误的电子邮件子例程,但我想知道是否有更好的方法。这种当前实现的缺陷是,如果在电子邮件子例程中发生错误,将会发生无限循环。
我正在处理一个执行很多事情的脚本,并且如果在执行过程中的任何时刻执行了“死亡”或发生了错误,我想向自己发送一封电子邮件。如果在Perl脚本中发生错误,发送电子邮件的最佳方式是什么?
我正在使用END块来检查退出状态,如果它大于0,则调用一个错误的电子邮件子例程,但我想知道是否有更好的方法。这种当前实现的缺陷是,如果在电子邮件子例程中发生错误,将会发生无限循环。
我用eval
和sendmail(因为它几乎总是安装):
eval
{
# do something
};
if ([email protected])
{
my $ip = `ifconfig`
or die "Can't ifconfig: $!\n";
my @now = localtime;
my $now = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $now[5]+1900, $now[4]+1, $now[3], $now[2], $now[1], $now[0]);
open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -fyou\@yourdomain.com")
or die "Can't fork for sendmail: $!\n";
print SENDMAIL << "EOF";
To: Your Name <you\@yourdomain.com>
Subject: ERROR: Exception
$now
[email protected]
$ip
EOF
close (SENDMAIL)
or warn "Sendmail didn't close nicely";
};
这将解决您的无限循环,但不会在万一发送一封电子邮件,该邮件块模具第一。我认为@jcomeau_ictx获得了防弹奖。
我也不知道如何在Windows中做到这一点。希望这可以帮助!
如果你是一个Unix系统中,包括(可能)的Mac OS/X上:./myscript.pl 2>/tmp/myscript.pl.log || mail -s 'myscript.pl failed' [email protected] < /tmp/myscript.pl.log
在Windows上,我不知道。
+1为鲁棒性! – mattexx 2011-03-09 00:59:00
我们真的来到这里两个独立的问题:
你如何(可靠)执行代码时,程序die
•不用创建一个无限循环,如果这个代码也命中一个致命的错误?
从Perl代码发送电子邮件的最佳方式是什么?
所以,单独回答每个:
不是一个END
块,我会用一个$SIG{__DIE__}
处理器(未测试的代码,但应该是正确的):
$SIG{__DIE__} = \&error_handler;
sub error_handler {
die @_ if $^S; # Do nothing if we died in an eval{}
delete $SIG{__DIE__}; # Clear handler in case following code also dies
print STDERR "Blue Wizard is about to die!\n";
}
当然,CPAN上有许多优秀的邮件发送模块。我从他们中间个人的偏好是MIME::Lite,这将使用由默认sendmail
邮件,但是,如果你使用的是Windows或没有sendmail
命令一些其他的系统,你可以使用MIME::Lite->send("smtp");
通过SMTP发送的情况下直接通过本地MTA会。还支持通过发送邮件服务器路由邮件(如果您的上游提供商阻止端口25,则方便!),并在需要时处理该服务器上的通用身份验证方法。
我个人的偏好是Net :: SMTP perl模块。有点冗长但非常全面。
my $mail = Net::SMTP->new($smtp_host);
$mail->mail("$login\@foo.com");
$mail->to("$login\@foo.com");
$mail->data();
#Generate email headers
$mail->datasend("From: Root <root\@foo.com>");
$mail->datasend("Subject: Status");
$mail->datasend("To: root\@foo.com");
$mail->datasend("\n") # Need one newline between headers and body
# Report data
$mail->datasend("Mail body here");
$mail->datasend("More mail body, repeat $mail->datasend() as needed");
# Then close connection
$mail->quit();
这两种方法都很好。我喜欢这个更多的是因为它适用于Windows,如果我取代Sendmail和我能够做到这一点是在Perl。谢谢! – Matthew 2011-03-09 01:29:04