Здравствуйте.
У меня на работе безлимитка, которой иногда хочется пользоваться. Например, закачивать много-много музыки, так, чтобы оставил, забыл на пару дней, вспомнил, а оно уже закачалось. Проблема в том, что безлимитка, все-таки, ограничена по скорости (30Kb/s), и если в наглую оставить закачку wget'ом, то никто этому рад не будет.
Я написал небольшой скриптик, который пингует яндекс, и на основании этого меняет скорость закачки:
Эта штука почти не мешает работе, разве что раз в пять минут на 20 секунд. И то, только если не повезет в этот момент освободить канал.
Но проблемы, все-таки, есть:
Собственно, теперь пара вопросов:
Кто-нибудь может подсказать более хороший и правильный способ для таких закачек?
Как можно улучшить этот скрипт, чтобы он стал хорошим и правильным способом?
UPD: Слегка подправил скрипт. Он теперь работает с конкретной работой (job) которую создает, и больше нет глобальных killall wget. Кроме того, пинг теперь не один, а столько, сколько захочется.
У меня на работе безлимитка, которой иногда хочется пользоваться. Например, закачивать много-много музыки, так, чтобы оставил, забыл на пару дней, вспомнил, а оно уже закачалось. Проблема в том, что безлимитка, все-таки, ограничена по скорости (30Kb/s), и если в наглую оставить закачку wget'ом, то никто этому рад не будет.
Я написал небольшой скриптик, который пингует яндекс, и на основании этого меняет скорость закачки:
#!/bin/bash
limit=1
delay=5
num_of_pings=3
while true
do
# Собственно, качаем. --limit-rate — это ограничение скорости. Обратите внимание на "&" в конце строки, он нужен, чтобы wget уходил в background
wget -t0 -c --limit-rate=$limit -q хттп://адрес_до_файла&
# Запоминаем номер работы, которую мы только что создали.
jobnum=`jobs %% | mawk '{if (NR==1) print $1}' | perl -pe 's/\[//; s/\]\+//'`
# Даем wget'у немного времени, чтобы поработать.
sleep $delay<br>
# Проверяем, не успел ли уже wget все закачать. Для этого смотрим jobs, находим там статус закачки (он либо Running, либо wget'а там нет вообще).
if [ "`jobs %$jobnum | mawk '{if (NR==1) print $2}'`" == "Running" ]
then
# Если еще не докачал, то прерываем его работу вручную.
kill %$jobnum
else
# Ну, а если докачал, то выходим из while'а, и большими шагами идем к выходу.
break
fi
# Даем сети немного времени успокоиться, чтобы результаты работы wget'а не влияли на замер скорости в следующей строчке
sleep 2
# Посылаем несколько пингов до яндекса и смотрим сколько времени они идут. Если среднее значение меньше 300 милисекунд, то считаем, что сеть свободна.
if [ `ping -c $num_of_pings ya.ru | grep time= | mawk '{print $8}' | perl -pe 's/time=//' | mawk '$1 ~ // {sum += $1}; END {sum /= '$num_of_pings'; print sum}' | perl -pe 's/\.[0-9]*//'` -le 300 ]
then
# Ага, сеть свободна. Тогда немножечко времени (20 секунд) качаем без ограничений.
limit=0
delay=20
else
# Упс, занято. Даем людям 5 минут спокойно поработать (закачка на уровне 100b/s).
limit=100
delay=300
fi
done
Эта штука почти не мешает работе, разве что раз в пять минут на 20 секунд. И то, только если не повезет в этот момент освободить канал.
Но проблемы, все-таки, есть:
- Когда канал свободен, он используется не на полную — теряются несколько секунд на простой, плюс, немного времени у wget'а на восстановление соединения.
- Этот скрипт принципиально не сработает, если сервер, с которого качаем файлы, не поддерживает докачку.
- Если скриптина таки зацапает себе канал, то придется ждать 20 секунд.
Собственно, теперь пара вопросов:
Кто-нибудь может подсказать более хороший и правильный способ для таких закачек?
Как можно улучшить этот скрипт, чтобы он стал хорошим и правильным способом?
UPD: Слегка подправил скрипт. Он теперь работает с конкретной работой (job) которую создает, и больше нет глобальных killall wget. Кроме того, пинг теперь не один, а столько, сколько захочется.