Bash: Wie erhalte ich den Exit-Code eines Befehls, während ich einen Spinner benutze?

Aug 19 2020

In einem Bash-Skript habe ich einen Befehl mit langer Laufzeit ( rsyncz. B.), der manchmal eine Weile lang keine Ausgabe anzeigt. Daher möchte ich zwei Dinge tun:

  1. Verwenden Sie einen Drehfeld für diesen Befehl, um anzuzeigen, dass das Skript nicht eingefroren ist (dh wir warten nur auf die Ausgabe). und,

  2. Rufen Sie den Beendigungsstatus des Befehls mit langer Laufzeit ab, sobald er ausgeführt wurde, und führen Sie später im Skript weitere Tests durch.

Das Problem ist jedoch, dass ich die Handhabung des Sendens von Prozessen im Hintergrund und auch die Handhabung des Exit-Codes auf diese Weise nicht sehr gut verstehe, sodass ich nicht sicher bin, wie dies funktionieren soll.

Folgendes habe ich bisher dank @David C. Rankins Spinner:

#!/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"

Ist in diesem Beispiel sleep 2der Befehl, auf den ich warte, und verwende daher den Spinner mit, aber wie erhalte ich den Exit-Code und setze ihn in eine $exitCodeVariable, damit ich ihn später im Skript auf bestimmte Bedingungen testen kann?

Antworten

6 CharlesDuffy Aug 19 2020 at 04:41

wait Hier erfahren Sie, mit welchem ​​Exit-Status eine untergeordnete PID beendet wurde (indem der Exit-Status dieses Programms als eigener festgelegt wurde), wenn diese PID als Argument angegeben wird.

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

echo "exitcode: $exitCode"

Beachten Sie, dass das Kombinieren mehrerer Befehle in einer Zeile beim Sammeln $!oder $?in der zweiten Hälfte eine dringend empfohlene Vorgehensweise ist. Sie verhindert, dass der Wert, den Sie sammeln möchten, versehentlich geändert wird (z. B. wenn jemand Ihrem Code eine neue Protokollzeile hinzufügt später und ohne es zu merken, hat es Nebenwirkungen).