Last active
August 2, 2022 21:54
-
-
Save epixoip/de857e35a73ad7b1dac0e3af602c05ba to your computer and use it in GitHub Desktop.
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/sh | |
# Wed Aug 26 19:25:48 PDT 2009 by epixoip | |
# a "download manager" tailored for comcast subscribers, ensuring "powerboost" | |
# speeds for the entire duration of a download. if you are unfamiliar with | |
# comcast powerboost: http://www.dslreports.com/faq/14520 | |
# (this is really just an excuse to write a "multi-threaded" shell script) | |
usage() { | |
cat >&2 <<EOF | |
powerboost - ensures comcast powerboost speeds for duration of download | |
Syntax: $0 [options] URL | |
Options: | |
-t Number of concurrent "threads" | |
-o Output file name | |
-h Display this message | |
EOF | |
exit 1 | |
} | |
error() | |
{ | |
echo "error: $1" >&2 | |
usage | |
} | |
warn() | |
{ | |
echo "warning: $1" >&2 | |
} | |
spawn_thread() | |
{ | |
r_start=$((r_end + 1)) | |
if test "$r_start" -gt "$filesize"; then | |
return | |
fi | |
r_end=$((r_start + 20000000)) | |
if test "$r_end" -gt "$filesize"; then | |
r_end="$filesize" | |
fi | |
chunk=$((chunk + 1)) | |
echo "Retrieving chunk $chunk ($r_start - $r_end)" | |
curl -so $outfile.$chunk -r $r_start-$r_end $url & | |
pids="$pids $!" | |
} | |
waitall() | |
{ | |
while true; do | |
for pid in "$@"; do | |
shift | |
if kill -0 "$pid" 2>/dev/null; then | |
set -- "$@" "$pid" | |
else | |
wait "$pid" | |
fi | |
done | |
if test "$#" -lt 1; then | |
break | |
fi | |
sleep 0.3 | |
done | |
} | |
while getopts "ht:o:" opts; do | |
case $opts in | |
t) threads="$OPTARG";; | |
o) outfile="$OPTARG";; | |
h) usage;; | |
?) usage;; | |
esac | |
x="$OPTIND" | |
done | |
if test -n "$x" && test "$x" -gt 0; then | |
shift $((x - 1)) | |
fi | |
if test -z "$1"; then | |
usage | |
fi | |
url="$1" | |
threads="${threads:-4}" | |
outfile="${outfile:-$(basename $url)}" | |
pids="" | |
filesize="$(curl -sI $url | sed -rn 's/Content-Length:\W+([0-9]+).*$/\1/ip')" | |
if test -z "$filesize"; then | |
error "$(basename $url) does not exist on server $(dirname $url)" | |
fi | |
maxthreads=$((filesize / 20000000)) | |
if test "$threads" -gt "$maxthreads"; then | |
warn "more threads were requested than needed; reducing threads to $maxthreads" | |
threads=$maxthreads | |
fi | |
r_start=0 | |
r_end=-1 | |
chunk=0 | |
start_time=$(date +%s) | |
set -o monitor | |
for t in $(seq 1 $threads); do | |
spawn_thread | |
sleep 0.3 | |
done | |
while test "$r_end" -lt "$filesize"; do | |
trap spawn_thread CHLD | |
wait | |
done | |
waitall $pids | |
end_time=$(date +%s) | |
elapsed=$((end_time - start_time)) | |
speed=$(echo "scale=2; $filesize / $elapsed" | bc) | |
echo "Retrieved $filesize bytes in $elapsed seconds [avg $speed bytes/sec]" | |
echo "Reassembling file..." | |
> $outfile | |
for i in $(seq 1 $chunk); do | |
cat $outfile.$i >>$outfile | |
rm -f $outfile.$i | |
done | |
echo 'Done!' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment