In a bash script, I have a long running command (say rsync
for example) that sometimes does not show output for a while, so I want to do two things:
Use a spinner on that command to show that the script hasn't frozen (i.e. we're just waiting for output); and,
Grab the exit status of the long running command once it's done, for further tests later in the script.
The problem is though, I don't understand the handling of sending processes to the background very well, and also with the handling of exit code this way, so I'm not sure how to make this work.
Here is what I have so far, thanks to @David C. Rankin's 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"
In this example, sleep 2
is the command I'm waiting for, and hence use the spinner with, but how do I get and put its exit code into $exitCode
variable, so I can test it for certain conditions later on in the script?
wait
will tell you what exit status a child PID exited with (by setting that program's exit status as its own), when given that PID as an argument.
sleep 2 & sleep_pid=$!
spinner "$sleep_pid"
wait "$sleep_pid"; exitCode=$?
echo "exitcode: $exitCode"
Note that combining multiple commands onto a line when collecting $!
or $?
in the second half is a practice I strongly recommend -- it prevents the value you're trying to collect from being changed by mistake (as by someone adding a new log line to your code later and not realizing it has side effects).