Parse maillog
Aller à la navigation
Aller à la recherche
| Fiche express | |
|---|---|
| Domaine | Extraction d'adresses mail depuis des fichiers de log |
| Outils | grep, cut, sed
|
| Voir aussi | Grep · Sed · Bash |
Script qui extrait toutes les adresses mail présentes dans un jeu de fichiers de log (typiquement des logs de MTA au format <adresse@domaine>), les dédoublonne, puis les insère dans une base MySQL — utile par exemple pour constituer une liste d'adresses observées à partir de journaux de courrier.
Script
#!/bin/bash
HOST_SQL=localhost
USER_SQL=collecte_mail
PASSWORD_SQL=
DATABASE_SQL=mail
# emplacement des fichiers source
DIR_FILE=/root/mail*
LISTE_MAIL=liste_mail.txt
TMP_MAIL=$(mktemp)
for file in ${DIR_FILE}; do
grep '@' "$file" | cut -d'<' -f2- | cut -d'>' -f1 >> "$TMP_MAIL"
grep '@' "$file" | cut -d'<' -f3- | cut -d'>' -f1 >> "$TMP_MAIL"
done
sort -u "$TMP_MAIL" > "$LISTE_MAIL"
rm -f "$TMP_MAIL"
# insertion en base, une ligne à la fois (lent sur un gros volume)
while IFS= read -r mail; do
mysql -h "$HOST_SQL" -u "$USER_SQL" -p"$PASSWORD_SQL" "$DATABASE_SQL" \
-e "INSERT INTO mail (adresse) VALUES ('${mail//\'/}')"
done < "$LISTE_MAIL"
Corrections apportées par rapport au script d'origine :
- les liens wiki
[[grep]]insérés directement dans les commandes (probablement collés depuis une page listant les commandes) rendaient le script invalide tel quel une fois copié-collé — remplacés par les commandes réelles. - boucle
for i in $(cat fichier)remplacée parwhile read(plus sûre sur des lignes contenant des espaces, bien que peu probable ici pour des adresses mail). - utilisation d'un fichier temporaire (
mktemp) au lieu d'un nom de fichier fixe (file_mail.tmp) qui pouvait entrer en collision entre deux exécutions concurrentes.
Points de vigilance
- Injection SQL : la valeur insérée n'est pas échappée pour MySQL, seule l'apostrophe est retirée (
${mail//\'/}) plutôt qu'échappée — une adresse contenant un autre caractère spécial SQL resterait un risque. Pour un usage au-delà d'un script ponctuel sur des données de confiance, préférer un import viaLOAD DATA INFILEou un vrai échappement (mysql --executene fait pas d'échappement automatique des valeurs interpolées côté shell). - Compte MySQL dédié : utiliser un compte applicatif avec les seuls droits nécessaires (
INSERTsur la table visée), pas un compte administrateur. - Performance : une requête
INSERTpar ligne est très lent sur un gros volume — unLOAD DATA INFILEou unINSERTmulti-lignes est nettement plus rapide.