Hello,

Alors je ne connaissais pas l'utilisation d'exec dans les scripts bash, et
ça me parrait très pratique (visiblement pour faire de la redirection de
toutes les sorties des commandes d'un script).

Je me suis un peu penché sur la question, et effectivement, tant que le
script n'est pas terminé, il semblerait que le fichier $RAPPORT soit
toujours ouvert, et son contenu peut ne pas être sauvegardé (surtout si le
filesystem utilise noatime il me semble). Mais techniquement, même avec
cette option, lorsque le script est terminé, le contenu du fichier $RAPPORT
doit être présent, même si ce dernier n'est pas encore réellement écrit sur
le disque.

D'après ce petit guide sur exec :

http://wiki.bash-hackers.org/commands/builtin/exec

Il faudrait mieux tout mettre ton script dans une fonction (main dans
l'exemple), lancer la fonction et récupérer le résultat dans le fichier de
sortie puis enfin analyser le fichier de sortie.

main() {

  echo "un truc"

}

main 2>&1 | while read line; do echo "[$(date '+%F %T')] $line" >> $RAPPORT
; done


# si le rapport est non vide on l'envoie
[ -s $RAPPORT ] && mail -s "rapport du $(date +%F)" root < $RAPPORT

Le 25 janvier 2016 à 10:52, Daniel Caillibaud <m...@lairdutemps.org> a écrit :

> Bonjour,
>
> J'ai de temps en temps un souci dans des scripts bash avec des écritures
> dans un fichier pas
> encore "vues" au moment où je regarde si y'en a eu.
>
> En gros, du
>
> # stdout dans un rapport (avec préfixe de date)
> exec > >(while read line; do echo "[$(date '+%F %T')] $line" >> $RAPPORT;
> done)
>
> echo "un truc"
> …
> # si le rapport est non vide on l'envoie
> [ -s $RAPPORT ] && mail -s "rapport du $(date +%F)" root < $RAPPORT
>
> Mais le test ci-dessus marche pas toujours, le fichier est parfois vu vide
> au moment du test
> alors qu'il y a bien eu une écriture de lancée (un test [ $(wc -l <
> $RAPPORT) -gt 0 ] ne fait
> pas mieux).
> C'est probablement lié à mon exec qui récupère la sortie standard et se
> fait visiblement en
> asynchrone, ou ne met pas à jour les infos en live, je sais pas exactement.
>
> Ajouter un sleep 1 avant de tester règle en général le pb, mais ça me
> parait pas très propre
> ni très fiable (pourquoi 1, pas sûr que ça suffise toujours, etc.).
>
> Un sync avant de tester fonctionnerait probablement, mais c'est trop
> violent (ça synchronise
> tout le filesystem, sur une machine avec un moteur de base de données
> chargé ça peut figer un
> peu trop longtemps les I/O à un mauvais moment).
>
> Une idée pour faire ça correctement ?
>
> Merci
>
> --
> Daniel
>
>

Répondre à