Barre chargement

De wiki.nexiat.fr
Aller à la navigation Aller à la recherche
Fiche express
Domaine Indicateur de progression en shell
Technique boucle d'attente en tâche de fond
Alternative robuste suivi par PID (kill -0)
Voir aussi Bash · Debug shell

Une barre de chargement (ou indicateur d'activité) en shell est une technique d'affichage minimal — points, spinner — pendant qu'une commande longue s'exécute, pour signaler que le script n'est pas figé. Bash n'a pas de widget de progression natif : ces effets reposent tous sur une boucle qui tourne en tâche de fond pendant que la commande principale s'exécute au premier plan.

Boucle de scrutation via ps/grep

Technique historique : une boucle en arrière-plan surveille la table des process avec ps/grep et affiche un point tant que le processus surveillé existe.

echo "Vérification des mises à jour système :"
while ps aux | grep -e [y]um > /dev/null; do
    echo -n "."
    sleep 1
done &
maj=$(yum -e 0 -d 0 check-update | awk '{print $1}')

Deux détails à comprendre :

  • la boucle est lancée en tâche de fond (&) avant la commande yum ; tant que ps aux trouve un processus yum, elle affiche un point chaque seconde, puis s'arrête d'elle-même quand yum se termine.
  • grep -e [y]um (plutôt que grep yum) évite que la commande grep ne se détecte elle-même dans la sortie de ps — la classe de caractères [y]um ne correspond à aucune ligne contenant littéralement [y]um, seulement à yum.

Limite : il y a une condition de course au démarrage — si la boucle teste ps avant que le processus yum n'apparaisse réellement, elle peut s'arrêter immédiatement sans avoir rien affiché. Cette technique reste fragile et dépend du nom du processus scruté ; à réserver aux cas où on ne maîtrise pas le PID exact de la commande surveillée.

Alternative plus robuste : suivi par PID

Quand on lance soi-même la commande longue, il est plus fiable de suivre son PID directement plutôt que de chercher son nom dans ps :

longue_commande &
pid=$!

while kill -0 "$pid" 2>/dev/null; do
    echo -n "."
    sleep 1
done
echo " terminé"

kill -0 n'envoie aucun signal, il teste juste l'existence du processus ; $! contient le PID du dernier job lancé en arrière-plan. Cette forme évite toute condition de course et ne dépend pas du nom de la commande.

Spinner rotatif

Variante plus visuelle qu'une suite de points, un caractère qui tourne :

spin() {
    local -a frames=('|' '/' '-' '\')
    local i=0
    while kill -0 "$1" 2>/dev/null; do
        printf '\r%s' "${frames[i]}"
        i=$(( (i + 1) % 4 ))
        sleep 0.2
    done
    printf '\r'
}

longue_commande &
spin $!

Voir aussi

  • Bash — boucles, variables spéciales ($!, $?) et gestion des tâches de fond
  • Debug shell — techniques de journalisation d'un script en cours d'exécution