web-dev-qa-db-fra.com

Comment envoyer des caractères spéciaux par courrier électronique à partir d'un script Shell?

J'ai un script qui tourne sur cron et qui génère du texte que nous envoyons au programme 'mail'. La ligne générale est comme ceci:

./command.sh | mail -s "My Subject" [email protected] -- -F "Sender Name" -f [email protected]

Le problème est que le texte généré par le script contient des caractères spéciaux - é, ã, ç - puisqu'il n'est pas en anglais. Lorsque l'e-mail est reçu, chaque caractère est remplacé par ??.

Je comprends maintenant que cela est probablement dû à un codage mal défini. Quel est le moyen le plus simple de résoudre ce problème?

18
JohnWithoutArms

Mon /usr/bin/mail est lié à /etc/alternatives/mail qui est également lié à /usr/bin/bsd-mailx

Je devais me spécifier le codage dans l'en-tête du mail. (Le -S n'est pas pris en charge ici.)

cat myutf8-file | mail -a "Content-Type: text/plain; charset=UTF-8" -s "My Subject" [email protected]

20
KumZ

Vous avez raison de supposer qu'il s'agit d'un problème de jeu de caractères. Vous devez définir les variables d'environnement appropriées au début de votre crontab.

Quelque chose comme ça devrait marcher:

LANG=en_US.UTF-8
LC_CTYPE=en_US.UTF-8

Vous pouvez éventuellement utiliser LC_ALL à la place de LC_CTYPE. 

Référence: http://opengroup.org/onlinepubs/007908799/xbd/envvar.html

Edit: La raison pour laquelle il affiche bien lorsque vous l'exécutez dans votre shell est probablement parce que les vars env ci-dessus sont définis dans votre shell.

Pour vérifier, exécutez 'locale _' dans votre shell, puis comparez-le au résultat d'un travail cron qui exécute la même commande.

Re-Edit : Ok, donc ce n’est pas un problème d’env var. 

Je suppose que vous utilisez mailx, comme c'est le plus courant de nos jours. Sa page de manuel dit:

Le jeu de caractères pour les messages sortants N'est pas nécessairement le même Que celui utilisé sur le terminal. Si un message texte sortant Contient Caractères non représentables dans US-ASCII, le jeu de caractères utilisé Doit être déclaré dans son en-tête. Les valeurs permises peuvent être déclarées À l’aide de la variable sendcharsets,

Donc, essayez d'ajouter les arguments suivants lorsque vous appelez mail:

-S sendcharsets=utf-8,iso-8859-1
10
Casey

j'ai écrit une fonction bash pour envoyer un email aux destinataires. La fonction envoie des mails encodés en utf-8 et fonctionne avec des caractères utf-8 dans le sujet et le contenu en encodant en base64.

Pour envoyer un email en texte brut:

send_email "plain" "[email protected]" "subject" "contents" "[email protected]" "[email protected]" "[email protected]" ...

Pour envoyer un email HTML:

send_email "html" "[email protected]" "subject" "contents" "[email protected]" "[email protected]" "[email protected]" ...

Voici le code de fonction.

# 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()
4
Biapy

Juste pour donner des informations supplémentaires à la réponse de KumZ: Si vous avez besoin de spécifier plus d’en-têtes avec le paramètre -a, n'hésitez pas à les additionner, comme ceci (notez le polyusage de -a).

echo /path/to/file | mail -s "Some subject" [email protected] -a "From: Human Name <[email protected]>" -a "Content-Type: text/plain; charset=UTF-8"
2
Fabien Haddadi

Vous pouvez utiliser la commande sendmail directement sans mail wrapper/helper.
Il vous permettrait de générer tous les en-têtes requis pour le corps "brut" UTF-8.
(UTF-8 est mentionné dans les commentaires du demandeur),

AVERTISSEMENT-1 :
Non 7bit / ASCII caractères dans les en-têtes (par exemple, Subject:, From:, To:) requiert codage spécial
WARNING-2 :
sendmail peut rompre les longues lignes (> 990 octets). 

[email protected]
SENDER_NAME="Sender Name"
[email protected]
(
# BEGIN of mail generation chain of commands
# "HERE" document with all headers and headers-body separator
cat << END
Subject: My Subject
From: $SENDER_NAME <$SENDER_ADDR>
To: $RECIPIENT_ADDR
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

END
# custom script to generate email body
./command.sh
# END   of mail generation chain of commands
) | /usr/sbin/sendmail -i -f$SENDER_ADDR -F"$SENDER_NAME" $RECIPIENT_ADDR
2
AnFi

utilisez l'option -o message-charset="utf-8", comme ça:

sendemail -f your_email -t destination_email -o message-charset="utf-8" -u "Subject" -m "Message" -s smtp-mail.Outlook.com:587 -xu your_mail -xp your_password
0
Rodolfo Dirack

Ce n'est probablement pas un problème de ligne de commande, mais un problème de jeu de caractères. Habituellement, lors de l’envoi de courriels, le jeu de caractères est iso-8859-1. Très probablement, le texte que vous mettez dans le processus n'est pas codé en iso-8859-1. Vérifiez le codage de la source de données à partir de laquelle vous obtenez le texte.

Lien obligatoire "bonne lecture": Le minimum absolu que chaque développeur de logiciel a absolument, doit savoir absolument sur Unicode et les jeux de caractères (pas d'excuses!)

Concernant votre mise à jour: Dans ce cas, si vous entrez les caractères spéciaux manuellement, votre terminal utilise peut-être le codage UTF-8. Vous devriez être capable de convertir le jeu de caractères du fichier en utilisant iconv par exemple. L’autre solution consisterait à indiquer à mail d’utiliser le codage UTF-8, mais le code IIRC n’est pas tout à fait trivial.

0
Pekka 웃