écriture à partir d’une fonction dans un script Bash, fuite de descripteurs de fichiers

Nous avons un script shell appelé par cron et exécuté en tant que root.

Ce script génère des informations de journalisation et de débogage et échoue à un certain moment. Ce point varie en fonction de la quantité de sortie créée par le script (il échoue plus rapidement si nous activons plus de sorties de débogage, par exemple).

Cependant, si le script est appelé directement en tant qu’utilisateur, cela fonctionne sans problème.

Nous avons depuis créé un cas de test simplifié qui illustre le problème.

Le script est:

#!/bin/bash function log_so () { local msg="$1" if [ -z "${LOG_FILE}" ] ; then warn_so "It's pointless use log_so() if LOG_FILE variable is undefined!" ; return 1 ; fi echo -e "${msg}" echo -e "${msg}" >> ${LOG_FILE} ( /bin/true ) } LOG_FILE="/usr/local/bin/log_bla" linenum=1 while [[ $linenum -lt 2000 ]] ; do log_so "short text: $linenum" let linenum++ done 

La valeur maximale atteinte est de 244 avant de mourir (lorsqu’elle est appelée via cron).

D’autres recherches recommandent d’utiliser un sous-shell no-op à partir de la fonction et d’appeler également / bin / true, mais non seulement cela ne fonctionne pas, mais l’option de sous-shell n’est pas réalisable dans le script principal.

Nous avons également essayé de modifier la limite du descripteur de fichier pour root, mais cela n’a pas aidé, et nous avons essayé d’utiliser à la fois #! / Bin / sh et #! / Bin / bash pour le script.

Nous utilisons la version 4.1.5 (1) de bash sur Ubuntu 10.04 LTS.

Toute idée ou recommandation pour une solution de contournement serait appréciée.

Pourquoi ne pas ouvrir un fd à la main et le nettoyer ensuite? Je n’ai pas de bash 4.1 à tester, mais cela pourrait aider.

 LOG_FILE="/usr/local/bin/log_bla" exec 9<> "$LOG_FILE" function log_so () { local msg="$1" if [ -z "${LOG_FILE}" ] ; then warn_so "It's pointless use log_so() if LOG_FILE variable is undefined!" ; return 1 ; fi echo -e "${msg}" echo -e "${msg}" >&9 return 0 } linenum=1 while [[ $linenum -lt 2000 ]] ; do log_so "short text: $linenum" let linenum++ done exec 9>&-