Skip to content

Instantly share code, notes, and snippets.

@Maik93
Created October 3, 2025 08:29
Show Gist options
  • Select an option

  • Save Maik93/e9948eb330d15648f047c338832aaf1d to your computer and use it in GitHub Desktop.

Select an option

Save Maik93/e9948eb330d15648f047c338832aaf1d to your computer and use it in GitHub Desktop.
Pacman package downloads for slow connections

Slow pacman updates that suddenly crash?

Classical problem:

error: failed retrieving file ... : Operation too slow. Less than 1 bytes/sec transferred the last 10 seconds

Just use this custom curl wrapper

  • Copy the file below into /usr/local/bin/pacman-curl
  • Update /etc/pacman.conf:
XferCommand = /usr/local/bin/pacman-curl %o %u
ParallelDownloads = 1 # suggested
  • enjoy!
#!/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"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment