Last active
March 28, 2025 21:43
-
-
Save felixr/936d4b43e26502396a15f2b2f1a67178 to your computer and use it in GitHub Desktop.
bash: run multiple commands and show last line of output
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
TMPDIR="$(mktemp -d)" | |
cmd_status() { | |
local pid=$1 | |
local cmd=$2 | |
local log=$3 | |
if ps h ${PIDS[$cmd_idx]} > /dev/null; then | |
echo -e "› \033[32m${cmd}\033[0m" | |
else | |
wait $pid | |
code=$? | |
echo -e "✔ [${code}] \033[90m${cmd}\033[0m" | |
fi | |
tail -n10 "${log}" 2>/dev/null | |
} | |
SPINNER=("( ● )" "( ● )" "( ● )" "( ● )" "( ●)" "( ● )" | |
"( ● )" "( ● )" "( ● )" "(● )") | |
spinner() { | |
local i=$1 | |
i=$(( i % ${#SPINNER[@]} )) | |
echo -n "${SPINNER[$i]}" | |
} | |
CMDS=( | |
"ping -c 10 google.com" | |
"vmstat 1 5" | |
"find /usr -type f" | |
"exit 255" | |
) | |
PIDS=() | |
cleanup () { | |
tput cnorm; | |
# Kill background jobs | |
if [[ ${#PIDS[@]} -gt 0 ]]; then | |
kill -15 "${PIDS[@]}" > /dev/null 2>&1 | |
sleep 0.5 | |
kill -9 "${PIDS[@]}" > /dev/null 2>&1 | |
echo "KILLED" | |
fi | |
rm -rf -- "$TMPDIR" | |
} | |
trap cleanup SIGINT SIGTERM | |
# Start the jobs | |
idx=0 | |
for ((i = 0; i < ${#CMDS[@]}; i++)); do | |
${CMDS[$i]} &> ${TMPDIR}/cmd_${idx}.log & PIDS+=($!) | |
idx=$((idx+1)) | |
done | |
update_loop() { | |
tput civis # cursor invisible | |
local num_lines=0 | |
local cnt=0 | |
local done=0; | |
while true; do | |
test ${num_lines} -gt 0 && tput cuu $num_lines | |
echo "Running ${idx} commands $(spinner $cnt)" | |
num_lines=1 | |
cnt=$((cnt+1)) | |
for cmd_idx in $(seq 0 $((idx -1))); do | |
logfile="${TMPDIR}/cmd_$cmd_idx.log" | |
output=$(cmd_status "${PIDS[cmd_idx]}" "${CMDS[cmd_idx]}" "${logfile}") | |
output_lines=$(echo "${output}" | wc -l) | |
while IFS= read -r line; do | |
tput cr; tput el #clear_line | |
echo -e "${line}" | |
done <<< "${output}" | |
num_lines=$((num_lines + output_lines)) | |
done | |
[[ $done == 1 ]] && break | |
jobs | grep Run >/dev/null || done=1 | |
sleep 0.2 | |
done | |
tput cnorm # cursor normal = visible | |
} | |
update_loop | |
cleanup |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment