如何通过邮件从shell脚本发送特殊字符?

Joh*_*rms 21 email shell encoding

我有一个在cron上运行的脚本,它输出一些我们发送到'mail'程序的文本.总路线是这样的:

./command.sh | mail -s "My Subject" destination@address.com -- -F "Sender Name" -f sender@address.com
Run Code Online (Sandbox Code Playgroud)

问题是脚本生成的文本有一些特殊的字符 - é,ã,ç - 因为它不是英文的.收到电子邮件后,每个字符都被??替换.

现在我明白这很可能是由于未正确设置的编码.解决这个问题的最简单方法是什么?

Kum*_*umZ 22

/usr/bin/mail的符号链接/etc/alternatives/mail也符号链接到/usr/bin/bsd-mailx

我不得不在邮件头中指定自己的编码.(-S这里不支持.)

cat myutf8-file | mail -a "Content-Type: text/plain; charset=UTF-8" -s "My Subject" me@mail.com

  • 运行该命令错误时出现以下错误:`"Content-Type:text/plain; charset = UTF-8:没有这样的文件或目录`.在查阅了`mail`的联机帮助页后,看来`-a`选项应该用于指定附件. (3认同)
  • @GeorgeEdison这可能是特定于分发的.在Ubuntu 12.04``a`定义了额外的头字段(使用包`bsd-mailx`).此外,手册页指出:_"mailx实用程序符合IEEE Std 1003.1-2008("POSIX.1")规范.标志[-abcdeEIv]是**规范的**扩展名."_所以, `-a`未在POSIX.1规范中定义. (2认同)
  • 这适用于邮件正文,谢谢。更一般地说,人们也需要在标头中使用 UTF-8 编码,根据 http://tools.ietf.org/html/rfc2047 和更新版本,此解决方案不包括在内。 (2认同)

Cas*_*sey 11

你认为这是一个charset问题你是对的.您需要将适当的环境变量设置为crontab的开头.

这样的事情应该有效:

LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8
Run Code Online (Sandbox Code Playgroud)

可选择使用LC_ALL代替LC_CTYPE.

参考:http://opengroup.org/onlinepubs/007908799/xbd/envvar.html

编辑:在shell中运行它时显示正常的原因可能是因为上面的env变量是在shell中设置的.

要验证,请在shell中执行' locale ',然后与运行相同命令的cronjob的输出进行比较.

重新编辑:好的,所以这不是一个env var问题.

我假设你正在使用mailx,因为它是现在最常见的.它的手册页说:

传出消息的字符集不一定与终端上使用的字符集相同.如果传出文本消息包含不能用US-ASCII表示的字符,则必须在其标题内声明正在使用的字符集.可以使用sendcharsets变量声明允许的值,

因此,在调用mail时尝试添加以下参数:

-S sendcharsets=utf-8,iso-8859-1
Run Code Online (Sandbox Code Playgroud)


Fab*_*adi 6

只是为了给 KumZ 答案提供更多信息:如果您需要使用 -a 开关指定更多标题,请随意添加它们,像这样(注意 -a 的多用途)。

echo /path/to/file | mail -s "Some subject" recipient@theirdomain.com -a "From: Human Name <noreply@mydomain.com>" -a "Content-Type: text/plain; charset=UTF-8"
Run Code Online (Sandbox Code Playgroud)


Bia*_*apy 5

我已经编写了一个bash函数来向收件人发送电子邮件。该函数发送utf-8编码的邮件,并通过执行base64编码来处理主题和内容中的utf-8字符。

要发送纯文本电子邮件:

send_email "plain" "from@domain.com" "subject" "contents" "to@domain.com" "to2@domain.com" "to3@domain.com" ...
Run Code Online (Sandbox Code Playgroud)

要发送HTML电子邮件:

send_email "html" "from@domain.com" "subject" "contents" "to@domain.com" "to2@domain.com" "to3@domain.com" ...
Run Code Online (Sandbox Code Playgroud)

这是功能代码。

# Send a email to recipients.
#
# @param string $content_type Email content mime type: 'html' or 'plain'.
# @param string $from_address Sender email.
# @param string $subject Email subject.
# @param string $contents Email contents.
# @param array $recipients Email recipients.
function send_email() {
  [[ ${#} -lt 5 ]] && exit 1

  local content_type="${1}"
  local from_address="${2}"
  local subject="${3}"
  local contents="${4}"

  # Remove all args but recipients.
  shift 4

  local encoded_contents="$(base64 <<< "${contents}")"
  local encoded_subject="=?utf-8?B?$(base64 --wrap=0 <<< "${subject}")?="

  for recipient in ${@}; do
    if [[ -n "${recipient}" ]]; then
    sendmail -f "${from_address}" "${recipient}" \
        <<< "Subject: ${encoded_subject}
MIME-Version: 1.0
From: ${from_address}
To: ${recipient}
Content-Type: text/${content_type}; charset=\"utf-8\"
Content-Transfer-Encoding: base64
Content-Disposition: inline

${encoded_contents}"
    fi
  done

  return 0
} # send_message()
Run Code Online (Sandbox Code Playgroud)


Pek*_*ica 0

这可能不是命令行问题,而是字符集问题。通常发送电子邮件时,字符集为iso-8859-1. 您放入进程中的文本很可能不是 iso-8859-1 编码的。检查您从中获取文本的任何数据源的编码是什么。

必读的“好读”链接:每个软件开发人员绝对必须了解的最低限度关于 Unicode 和字符集的知识(没有任何借口!)

重新更新:在这种情况下,如果您手动输入特殊字符,则您的终端可能使用 UTF-8 编码。您应该能够使用iconv例如转换文件的字符集。另一种方法是告诉mail使用 UTF-8 编码,但 IIRC 这并不完全是微不足道的。