|
#!/usr/bin/env bash |
|
# pacman-curl: quiet curl + our own progress bar (filename + ###) |
|
out="$1"; url="$2" |
|
|
|
# show nice name without .part |
|
base="$(basename "${out%.part}")" |
|
|
|
# try to get total size (may be empty if server doesn't send it) |
|
total=$(curl -sIL -o /dev/null -w '%{size_download}\n' "$url") |
|
if [[ -z "$total" || "$total" -eq 0 ]]; then |
|
total=$(curl -sIL "$url" | awk -v IGNORECASE=1 '/^Content-Length:/ {print $2}' | tail -n1 | tr -d '\r') |
|
fi |
|
|
|
# start the download (silent, resumable, retries) |
|
# (stderr quiet; errors still printed) |
|
curl -L -C - --retry 20 --retry-delay 5 --connect-timeout 30 -sS -o "$out" "$url" & |
|
cpid=$! |
|
|
|
bar_w=32 |
|
draw() { |
|
local got="$1" pct=0 done=0 bar fill |
|
if [[ -n "$total" && "$total" -gt 0 ]]; then |
|
pct=$(( got*100/total )) |
|
(( pct>100 )) && pct=100 |
|
done=$(( pct*bar_w/100 )) |
|
else |
|
# unknown size => animate bar based on bytes |
|
done=$(( (got/131072) % (bar_w+1) )) |
|
fi |
|
bar=$(printf '%*s' "$done" '' | tr ' ' '#') |
|
fill=$(printf '%*s' $((bar_w-done)) '' | tr ' ' ' ') |
|
if [[ -n "$total" && "$total" -gt 0 ]]; then |
|
printf '\r%s [%s%s] %3d%%' "$base" "$bar" "$fill" "$pct" >&2 |
|
else |
|
# no total => show bytes |
|
printf '\r%s [%s%s] %s' "$base" "$bar" "$fill" "$(numfmt --to=iec --suffix=B $got 2>/dev/null || echo ${got}B)" >&2 |
|
fi |
|
} |
|
|
|
# monitor file size and draw bar until curl exits |
|
while kill -0 "$cpid" 2>/dev/null; do |
|
f="$out" |
|
[[ -e "$out.part" ]] && f="$out.part" |
|
got=$(stat -c %s "$f" 2>/dev/null || echo 0) |
|
draw "$got" |
|
sleep 0.2 |
|
done |
|
|
|
wait "$cpid"; rc=$? |
|
|
|
# final draw to 100% if we know total, then newline |
|
if [[ "$rc" -eq 0 ]]; then |
|
f="$out" |
|
[[ -e "$out.part" ]] && f="$out.part" |
|
got=$(stat -c %s "$f" 2>/dev/null || echo 0) |
|
[[ -n "$total" && "$total" -gt 0 ]] && draw "$total" || draw "$got" |
|
printf '\n' >&2 |
|
fi |
|
|
|
exit "$rc" |