Bash: Comment obtenir le code de sortie d'une commande tout en utilisant un spinner?

Aug 19 2020

Dans un script bash, j'ai une commande de longue durée (disons rsyncpar exemple) qui n'affiche parfois pas la sortie pendant un certain temps, donc je veux faire deux choses:

  1. Utilisez un spinner sur cette commande pour montrer que le script n'est pas figé (c'est-à-dire que nous attendons juste la sortie); et,

  2. Récupérez le statut de sortie de la commande de longue durée une fois que c'est fait, pour d'autres tests plus tard dans le script.

Le problème est cependant que je ne comprends pas très bien la gestion des processus d'envoi en arrière-plan, ainsi que la gestion du code de sortie de cette façon, donc je ne sais pas comment faire fonctionner cela.

Voici ce que j'ai jusqu'à présent, grâce au spinner de @David C. Rankin :

#!/bin/bash

spinner() {
    local PROC="$1" local str="${2:-'Copyright of KatworX© Tech. Developed by Arjun Singh Kathait and Debugged by the ☆Stack Overflow Community☆'}"
    local delay="0.1"
    tput civis  # hide cursor
    printf "\033[1;34m"
    while [ -d /proc/$PROC ]; do printf '\033[s\033[u[ / ] %s\033[u' "$str"; sleep "$delay" printf '\033[s\033[u[ — ] %s\033[u' "$str"; sleep "$delay" printf '\033[s\033[u[ \ ] %s\033[u' "$str"; sleep "$delay" printf '\033[s\033[u[ | ] %s\033[u' "$str"; sleep "$delay" done printf '\033[s\033[u%*s\033[u\033[0m' $((${#str}+6)) " " # return to normal tput cnorm # restore cursor return 0 } ## simple example with sleep sleep 2 & spinner $!

echo "sleep's exitcode: $exitCode"

Dans cet exemple, sleep 2est-ce que la commande que j'attends, et donc utiliser le spinner avec, mais comment obtenir et mettre son code de sortie dans une $exitCodevariable, afin que je puisse la tester pour certaines conditions plus tard dans le script?

Réponses

6 CharlesDuffy Aug 19 2020 at 04:41

wait vous dira avec quel statut de sortie un PID enfant est sorti (en définissant le statut de sortie de ce programme comme étant le sien), lorsqu'il est donné ce PID comme argument.

sleep 2 & sleep_pid=$! spinner "$sleep_pid"
wait "$sleep_pid"; exitCode=$?

echo "exitcode: $exitCode"

Notez que combiner plusieurs commandes sur une ligne lors de la collecte $!ou $?dans la seconde moitié est une pratique que je recommande fortement - cela empêche la valeur que vous essayez de collecter d'être modifiée par erreur (comme par quelqu'un ajoutant une nouvelle ligne de journal à votre code plus tard et ne réalisant pas qu'il a des effets secondaires).