Exécuter une commande en temps limité

Sommaire

Ce petit script bash prend une commande et un délai en paramètre. Il lance la commande et la termine si elle dépasse le délai prévu. La procédure d’exécution en temps limitée peut aussi être facilement exploitée dans un script.

Le script

#!/bin/bash

# Nom du programme à exécuter
PROGRAMME="${1}"
# Délai maximal d'exécution
DELAI_MAX="${2}"

execution_en_temps_limite() {

  # Nom du programme à exécuter
  typeset PROGRAMME="${1}"
  # Délai maximal d'exécution
  typeset DELAI_MAX="${2}"

  typeset FICHIER_RETOUR="$( mktemp )" || exit 1
  typeset CODE_RETOUR=0
  typeset A_ETE_TUE=0

  # Lancement du chronomètre
  sleep "${DELAI_MAX}s" &
  typeset PID_SLEEP="${!}"

  # Lancement du programme
  ( ${PROGRAMME} ; echo "${?}" > "${FICHIER_RETOUR}" ; kill -ALRM "${PID_SLEEP}" ) &
  typeset PID_PROGRAMME="${!}" 
  wait "${PID_SLEEP}" 2>/dev/null

  if ps "${PID_PROGRAMME}" > /dev/null 2>&1 ; then
    # Le processus est toujours là
    disown "${PID_PROGRAMME}"
    kill "${PID_PROGRAMME}"
    A_ETE_TUE=1
  fi

  # Récupération du résultat
  if [ -f "${FICHIER_RETOUR}" ] && [ -s "${FICHIER_RETOUR}" ] ; then
    CODE_RETOUR="$( cat "${FICHIER_RETOUR}" )"
    rm -f "${FICHIER_RETOUR}"
  fi

  # Analyse du résultat et retour de la fonction
  if [ "${A_ETE_TUE}" -eq 1 ] ; then
    return 1
  else
    # Le processus a disparu
    return "${CODE_RETOUR}"
  fi

}

if execution_en_temps_limite "${PROGRAMME}" "${DELAI_MAX}" ; then
  echo "${PROGRAMME} s'est terminé dans le délai prévu"
else
  S="$( gawk -v D="${DELAI_MAX}" 'BEGIN { if ( D >= 2 ) { print "s" } }')"
  echo "${PROGRAMME} ne s'est pas terminé en ${DELAI_MAX} seconde${S} ou a échoué"
fi

Un essai

Sauvegardons le script sous le nom temps_limité.sh, puis exécutons-le avec une commande trop longue, en lui donnant une limite d’une seconde :

$ time ./temps_limité.sh "sleep 10s" 1
sleep 10s ne s'est pas terminé en 1 seconde ou a échoué

real    0m1,032s
user    0m0,004s
sys     0m0,029s

La commande s’est bien arrêté au bout du délai indiqué.


Licence : CC-BY