[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: sync sur un seul fichier



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 <ml@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



Reply to: