Garder ouvert un script shell

Je cherche à ce qu’un script shell reste ouvert comme un démon au lieu de rendre la main après s’être exécuté. Comme un démon, je veux qu’il réagisse en se termi­nant de lui-même quand il reçoit une demande de SIGTERM.

Ma première approche c’est une boucle infi­nie avec un sleep.

trap 'quit' SIGTERM SIGKILL

function quit() {
  exit 1
}

while true; do
  sleep 10
done 

Le trap n’in­ter­rompt pas le sleep. J’ai mis 10 secondes pour garder une réac­ti­vité raison­nable à l’ex­tinc­tion.

Même si un réveil toutes les 10 secondes est proba­ble­ment insi­gni­fiant, quelque chose en moi est quand même gêné et aurait aimé mettre plusieurs heures ici.

Je vois sur le web pas mal d’exemples avec un sleep 1, qui m’in­ter­roge encore plus. Quel est le coût réel de ce sleep 10 dans une boucle infi­nie ?

Certains ont élaboré des solu­tions pour rendre le sleep inter­rup­tible en l’en­voyant en tâche de fond :

PID=

trap '[[ $PID ]] && kill "$PID"' SIGTERM SIGKILL

while true; do
  sleep 100000 & pid=$!
  wait
done

Je vois aussi, et ça m’a l’air simple & smart, des scripts utili­ser des read­line plutôt que des sleep. Les read­line ont la bonne idée d’être inter­rup­tibles et de durée infi­nie tant qu’on n’en­voie rien sur stdin.

trap 'quit' SIGTERM SIGKILL

function quit() {
  exit 1
}

read

Dites, les amateurs de shell, quelle est la méthode recom­man­dée pour garder un script ouvert en tâche de fond ? Est-ce qu’il y a une réelle diffé­rence entre ces méthodes ou est-ce juste une ques­tion de style ?

Comments

5 réponses à “Garder ouvert un script shell”

  1. Avatar de Wtv
    Wtv

    Pourquoi pas utiliser & ? Ou nohup ?

    1. Avatar de Éric
      Éric

      Ça n’empêchera pas le script d’arriver à son terme, ça permettra juste de le faire passer en tâche de fond ou de le détacher de son parent

  2. Avatar de Xael
    Xael

    Le read ne fonctionne que si un TTY est associé au lancement, ce qui va bien si on le lance depuis un shell.

    1. Avatar de Éric
      Éric

      Oh, ça ne fonctionnera pas dans mon cas (lancement depuis launchd sur Mac, peu de chance qu’il y ait un tty attaché)

      Merci
      Dommage, je trouvais ça élégant

    2. Avatar de Breizh

      Ce n’est pas tout à fait vrai, j’ai un script shell qui utilise précisément la méthode du read en dehors d’un TTY (avec une attente de moins d’une seconde, mais parce que ce script gère une animation qui doit être mise à jour chaque seconde – c’est sale en vrai, mais ça marche).

      Cependant le programme qui l’appelle garde un pipe sur l’entrée standard de mon script (pour lui envoyer des informations dans certains cas), c’est peut-être ce qui fait que cela fonctionne ? Dans tous les cas cela vaut la peine d’essayer je pense.

      Sinon il y a d’autres méthodes, mais il faut savoir exactement pourquoi tu as besoin d’un script qui boucle. Si tu surveilles l’état d’un fichier par exemple, inotifywait (je sais pas si ça existe sur Mac cela dit) peut être intéressant, et dispose de sa propre option de timeout. watch peut aussi faire le travail. Même tail, en bricolant, peut être un bon moyen d’attendre, en utilisant la commande timeout pour avoir une limite de temps maximale.

      Bref, la meilleure réponse à ce problème Y dépends parfois du problème X initial…

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *