Bash: Como obter o código de saída de um comando ao usar um botão giratório?

Aug 19 2020

Em um script bash, tenho um comando de longa execução (digamos, rsyncpor exemplo) que às vezes não mostra a saída por um tempo, então quero fazer duas coisas:

  1. Use um botão giratório nesse comando para mostrar que o script não congelou (ou seja, estamos apenas esperando pela saída); e,

  2. Pegue o status de saída do comando de longa execução depois de concluído, para testes adicionais posteriormente no script.

O problema é que eu não entendo muito bem como lidar com o envio de processos para o segundo plano e também como lidar com o código de saída dessa maneira, então não tenho certeza de como fazer isso funcionar.

Aqui está o que eu tenho até agora, graças ao 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"

Neste exemplo, sleep 2é o comando pelo qual estou esperando e, portanto, uso o botão giratório com, mas como faço para obter e colocar seu código de saída na $exitCodevariável, para que possa testá-lo para certas condições posteriormente no script?

Respostas

6 CharlesDuffy Aug 19 2020 at 04:41

wait lhe dirá com qual status de saída um PID filho saiu (definindo o status de saída desse programa como seu), quando dado esse PID como um argumento.

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

echo "exitcode: $exitCode"

Observe que combinar vários comandos em uma linha ao coletar $!ou $?na segunda metade é uma prática que eu recomendo fortemente - evita que o valor que você está tentando coletar seja alterado por engano (como se alguém adicionasse uma nova linha de log ao seu código mais tarde e sem perceber que tem efeitos colaterais).