如何从 shell 脚本通过邮件发送特殊字符?
我有一个在 cron 上运行的脚本,它输出一些我们发送到“邮件”程序的文本。一般思路是这样的:
./command.sh | mail -s "My Subject" [email protected] -- -F "Sender Name" -f [email protected]
问题是脚本生成的文本有一些特殊字符 - é、ã、ç - 因为它不是英语。收到电子邮件后,每个字符都会替换为 ??。
现在我明白这很可能是由于编码设置不正确造成的。解决这个问题最简单的方法是什么?
I have a script that runs on cron that outputs some text which we send to the 'mail' program. The general line is like this:
./command.sh | mail -s "My Subject" [email protected] -- -F "Sender Name" -f [email protected]
The problem is that the text generated by the script has some special characters - é, ã, ç - since it is not in english. When the e-mail is received, each character is replaced by ??.
Now I understand that this is most likely due to the encoding that is not set correctly. What is the easiest way to fix this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
我的
/usr/bin/mail
符号链接到/etc/alternatives/mail
,它也符号链接到/usr/bin/bsd-mailx
我必须在邮件标头中指定自己的编码。 (此处不支持
-S
。)cat myutf8-file | mail -a“内容类型:text/plain;字符集=UTF-8”-s“我的主题”[电子邮件受保护]
My
/usr/bin/mail
is symlinked to/etc/alternatives/mail
which is also symlinked to/usr/bin/bsd-mailx
I had to specify myself the encoding in the mail header. (The
-S
is not supported here.)cat myutf8-file | mail -a "Content-Type: text/plain; charset=UTF-8" -s "My Subject" [email protected]
您假设这是字符集问题是正确的。您需要在 crontab 的开头设置适当的环境变量。
像这样的东西应该可以工作:
可以选择使用 LC_ALL 代替 LC_CTYPE。
参考:http://opengroup.org/onlinepubs/007908799/xbd/envvar.html
编辑: 当您在 shell 中运行它时显示良好的原因可能是因为上述环境变量是在您的 shell 中设置的。
要进行验证,请在 shell 中执行“locale”,然后与运行相同命令的 cronjob 的输出进行比较。
重新编辑:好的,所以这不是环境变量问题。
我假设您正在使用 mailx,因为它是当今最常见的。它的联机帮助页说:
因此,尝试在调用邮件时添加以下参数:
You're right in assuming this is a charset issue. You need to set the appropriate environment variables to the beginning of your crontab.
Something like this should work:
Optionally use LC_ALL in place of LC_CTYPE.
Reference: http://opengroup.org/onlinepubs/007908799/xbd/envvar.html
Edit: The reason it displays fine when you run it in your shell is probably because the above env vars are set in your shell.
To verify, execute 'locale' in your shell, then compare to the output of a cronjob that runs the same command.
Re-Edit: Ok, so it's not an env var problem.
I am assuming you're using mailx, as it is the most common nowdays. It's manpage says:
So, try and add the following arguments when calling mail:
我编写了一个 bash 函数来向收件人发送电子邮件。该函数发送 utf-8 编码的邮件,并通过执行 base64 编码来处理主题和内容中的 utf-8 字符。
发送纯文本电子邮件:
发送 HTML 电子邮件:
以下是功能代码。
i've written a bash function to send an email to recipients. The function send utf-8 encoded mails and work with utf-8 chars in subject and content by doing a base64 encode.
To send a plain text email:
To send a HTML email:
Here is the function code.
只是为了向 KumZ 回答提供更多信息:
如果您需要使用 -a 开关指定更多标头,请随意将它们添加起来,如下所示(请注意 -a 的多用途)。
Just to give additional information to KumZ answer:
if you need to specify more headers with the -a switch, feel free to add them up, like this (note the polyusage of -a).
您可以直接使用
sendmail
命令,无需mail
包装器/帮助器。它将允许您生成“原始”UTF-8 正文所需的所有标头
(提问者的评论中提到了UTF-8),
WARNING-1:
标头中的非 7bit/ASCII 字符(例如
Subject:
,< code>From:,To:)
需要特殊编码警告2:
sendmail 可能会中断长行(> 990 字节)。
You may use
sendmail
command directly withoutmail
wrapper/helper.It would allow you to generate all headers required for "raw" UTF-8 body
(UTF-8 is mentioned in asker's comments),
WARNING-1:
Non 7bit/ASCII characters in headers (e.g.
Subject:
,From:
,To:)
require special encodingWARNING-2:
sendmail may break long lines (>990 bytes).
rfc2045 - (5)(软换行符)Quoted-Printable 编码要求编码行的长度不超过 76 个字符。对于 bash shell 脚本代码:
rfc2045 - (5) (Soft Line Breaks) The Quoted-Printable encoding REQUIRES that encoded lines be no more than 76 characters long. For bash shell script code:
这可能不是命令行问题,而是字符集问题。通常发送电子邮件时,字符集为
iso-8859-1
。您放入进程中的文本很可能不是 iso-8859-1 编码的。检查您从中获取文本的任何数据源的编码是什么。必读的“好读”链接: 每个软件开发人员绝对必须了解 Unicode 和字符的绝对最低限度设置(没有借口!)
重新更新: 在这种情况下,如果您手动输入特殊字符,您的终端可能正在使用 UTF-8 编码。例如,您应该能够使用
iconv
转换文件的字符集。另一种方法是告诉mail
使用 UTF-8 编码,但 IIRC 这并不完全是微不足道的。This is probably not a command line issue, but a character set problem. Usually when sending E-Mails, the character set will be
iso-8859-1
. Most likely the text you are putting into the process is not iso-8859-1 encoded. Check out what the encoding is of whatever data source you are getting the text from.Obligatory "good reading" link: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!)
Re your update: In that case, if you enter the special characters manually, your terminal may be using UTF-8 encoding. You should be able to convert the file's character set using
iconv
for example. The alternative would be to tellmail
to use UTF-8 encoding, but IIRC that is not entirely trivial.使用选项
-o message-charset="utf-8"
,如下所示:use the option
-o message-charset="utf-8"
, like that:我有点晚了,但以前的解决方案都不适合我。
定位
mail
命令 (CentOS)所以 mail 命令实际上是 mailx。这有助于搜索,最终让我找到 Unix&Linux Stackexchange 上的这个答案,其中指出:
并:
因此解决方案是使用 tr 命令删除这些特殊字符。像这样的事情:
我已经用我的命令使用了这个解决方案
I'm a bit late but none of the previous solutions worked for me.
Locating
mail
command (CentOS)So mail command is in fact mailx. This helped with the search that finally took me to this answer at Unix&Linux Stackexchange that states:
From
man
page and:So the solution is using tr command to remove those special characters. Something like this:
I've used this solution with my command