Bash: come ottenere il codice di uscita di un comando durante l'utilizzo di uno spinner?

Aug 19 2020

In uno script bash, ho un comando a lunga esecuzione ( rsyncad esempio) che a volte non mostra l'output per un po ', quindi voglio fare due cose:

  1. Usa uno spinner su quel comando per mostrare che lo script non si è bloccato (cioè stiamo solo aspettando l'output); e,

  2. Prendi lo stato di uscita del comando a lunga esecuzione una volta terminato, per ulteriori test più avanti nello script.

Il problema è però che non capisco molto bene la gestione dell'invio dei processi in background, e anche la gestione del codice di uscita in questo modo, quindi non sono sicuro di come farlo funzionare.

Ecco cosa ho finora, grazie allo spinner di @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"

In questo esempio, sleep 2è il comando che sto aspettando e quindi uso lo spinner con, ma come ottengo e metto il suo codice di uscita nella $exitCodevariabile, in modo da poterlo testare per determinate condizioni più avanti nello script?

Risposte

6 CharlesDuffy Aug 19 2020 at 04:41

wait ti dirà con quale stato di uscita è uscito un PID figlio (impostando lo stato di uscita di quel programma come proprio), quando viene fornito quel PID come argomento.

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

echo "exitcode: $exitCode"

Nota che combinare più comandi su una riga durante la raccolta $!o $?nella seconda metà è una pratica che consiglio vivamente: impedisce che il valore che stai cercando di raccogliere venga modificato per errore (come se qualcuno aggiungesse una nuova riga di registro al tuo codice in seguito e non rendersi conto che ha effetti collaterali).