Bash: ¿Cómo obtener el código de salida de un comando mientras se usa una ruleta?

Aug 19 2020

En un script bash, tengo un comando de ejecución prolongada (digamos, rsyncpor ejemplo) que a veces no muestra la salida durante un tiempo, por lo que quiero hacer dos cosas:

  1. Use un control giratorio en ese comando para mostrar que el script no se ha congelado (es decir, solo estamos esperando la salida); y,

  2. Tome el estado de salida del comando de ejecución prolongada una vez que haya terminado, para realizar más pruebas más adelante en el script.

Sin embargo, el problema es que no entiendo muy bien el manejo del envío de procesos en segundo plano, y también el manejo del código de salida de esta manera, así que no estoy seguro de cómo hacer que esto funcione.

Esto es lo que tengo hasta ahora, gracias a la ruleta 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"

En este ejemplo, ¿ sleep 2es el comando que estoy esperando y, por lo tanto, con el que uso la ruleta, pero cómo obtengo y pongo su código de salida en la $exitCodevariable, para poder probarlo para ciertas condiciones más adelante en el script?

Respuestas

6 CharlesDuffy Aug 19 2020 at 04:41

wait le dirá con qué estado de salida salió un PID secundario (estableciendo el estado de salida de ese programa como propio), cuando se le proporcione ese PID como argumento.

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

echo "exitcode: $exitCode"

Tenga en cuenta que la combinación de varios comandos en una línea al recopilar $!o $?en la segunda mitad es una práctica que recomiendo encarecidamente: evita que el valor que está tratando de recopilar se cambie por error (como cuando alguien agrega una nueva línea de registro a su código más tarde y sin darse cuenta de que tiene efectos secundarios).