使用sendmail命令发送带TXT附件邮件的正确语法咨询
解决sendmail发送带附件邮件的语法错误问题
错误原因分析
你执行的命令同时使用了管道(echo ... | sendmail)和输入重定向(< 文件),shell无法判断sendmail的输入来源,因此抛出“Ambiguous input redirect”错误。另外,该命令只能将文件内容作为邮件正文发送,无法实现附件功能。
正确的shell命令写法(构造MIME邮件)
要发送带附件的邮件,需要手动构造符合MIME标准的邮件内容,示例如下:
( echo "Subject: Report" echo "To: vkk@test.com" echo "MIME-Version: 1.0" echo "Content-Type: multipart/mixed; boundary=\"MAIL_BOUNDARY\"" echo echo "--MAIL_BOUNDARY" echo "Content-Type: text/plain; charset=utf-8" echo echo "这里是邮件正文内容" echo echo "--MAIL_BOUNDARY" echo "Content-Type: text/plain; charset=utf-8; filename=\"report_daily_2022_08_24_19_30_17.txt\"" echo "Content-Disposition: attachment; filename=\"report_daily_2022_08_24_19_30_17.txt\"" echo cat "/usr/people/vkk/Downloads/report_daily_2022_08_24_19_30_17.txt" echo echo "--MAIL_BOUNDARY--" ) | sendmail -t
- 用括号将所有邮件内容的输出整合,通过管道传给sendmail
-t参数会从邮件头的To字段读取收件人,无需在命令行指定MAIL_BOUNDARY是自定义的分隔符,用于区分邮件正文和附件部分- 附件部分需指定
Content-Disposition: attachment来标记为附件
Perl脚本中更可靠的实现方式
手动构造MIME格式容易出错,推荐使用Perl邮件模块来实现,以下是两种常用方案:
方案1:使用Mail::Sendmail模块
use strict; use warnings; use Mail::Sendmail; # 配置邮件基本信息 my %mail_config = ( To => 'vkk@test.com', From => 'sender@test.com', # 必须指定发件人 Subject => 'Report', 'Content-Type' => 'multipart/mixed; boundary="PERL_MAIL_BOUNDARY"' ); # 构造邮件内容 my $mail_body = "--PERL_MAIL_BOUNDARY\n"; # 添加正文 $mail_body .= "Content-Type: text/plain; charset=utf-8\n\n"; $mail_body .= "这是邮件正文\n\n"; # 添加附件 $mail_body .= "--PERL_MAIL_BOUNDARY\n"; $mail_body .= "Content-Type: text/plain; charset=utf-8; filename=\"report_daily_2022_08_24_19_30_17.txt\"\n"; $mail_body .= "Content-Disposition: attachment; filename=\"report_daily_2022_08_24_19_30_17.txt\"\n\n"; # 读取附件文件内容 open my $fh, '<', '/usr/people/vkk/Downloads/report_daily_2022_08_24_19_30_17.txt' or die "无法打开附件文件: $!"; local $/; $mail_body .= <$fh>; close $fh; $mail_body .= "\n--PERL_MAIL_BOUNDARY--\n"; $mail_config{Message} = $mail_body; # 发送邮件 sendmail(%mail_config) or die "发送失败: $Mail::Sendmail::error";
方案2:使用Email::MIME + Email::Sender模块(更现代)
use strict; use warnings; use Email::MIME; use Email::Sender::Simple qw(sendmail); use Email::Sender::Transport::Sendmail; # 创建邮件对象 my $email = Email::MIME->create( header_str => [ To => 'vkk@test.com', From => 'sender@test.com', Subject => 'Report', ], parts => [ # 邮件正文 Email::MIME->create( attributes => { content_type => 'text/plain', charset => 'utf-8', }, body_str => '这是邮件正文内容', ), # 附件 Email::MIME->create( attributes => { filename => 'report_daily_2022_08_24_19_30_17.txt', content_type => 'text/plain', charset => 'utf-8', disposition => 'attachment', }, body => do { open my $fh, '<', '/usr/people/vkk/Downloads/report_daily_2022_08_24_19_30_17.txt' or die "无法打开附件: $!"; local $/; <$fh>; }, ), ], ); # 使用sendmail命令发送邮件 my $transport = Email::Sender::Transport::Sendmail->new; sendmail($email, { transport => $transport });
内容的提问来源于stack exchange,提问作者vkk05
相关产品推荐
相关产品推荐

