Хотя в принципе в конфе вопрос уже не раз обсуждался и предлагались разные скрипты для этой цели, тем не менее могу поделиться скриптом собственной разработки, который осуществляет закачку с помощью wget в 1 поток. Скрипт написан на tcl. Для его работы требуется установить tcl: ipkg install tcl
Добавление закачки производится путем добавления URL в текстовый файл ( /opt/tmp/wget/wget.list ), содержащий список закачек.
А вот собственно код:
/opt/local/bin/check.wget.tcl
PHP Code:
#! /bin/sh
# The next line is executed by /bin/sh, but not tcl \
exec tclsh8.4 "$0" ${1+"$@"}
set WGET_BIN [file join / opt bin wget]
set WGET_BASE [file join / opt tmp wget]
set WGET_LIST [file join $WGET_BASE wget.list]
set WGET_LIST_COMPLETED [file join $WGET_BASE wget.completed.list]
set WGET_LIST_NOT_FOUND [file join $WGET_BASE wget.not_found.list]
set WGET_LOG [file join $WGET_BASE wget.log]
set WGET_PARTIAL [file join $WGET_BASE partial]
set WGET_COMPLETED [file join $WGET_BASE completed]
proc FileToList {FileName} {
if {[catch {open $FileName r} f]} {
puts "Unable to open \"$FileName\" for reading; error $f."
exit
}
set lList {}
set str ""
while {![eof $f] } {
gets $f str
if {[string trim $str] ne ""} {
lappend lList [string trim $str]
}
}
close $f
return $lList
}
proc ListToFile {FileName lList} {
if {[catch {open $FileName w} f]} {
puts "Unable to open \"$FileName\" for writing; error $f."
exit
}
foreach i $lList {
puts $f [string trim $i]
}
close $f
}
set lList [FileToList $::WGET_LIST]
set CurrentURL [lindex $lList 0]
while {1} {
set CurrentConnections [regexp -all {bin/wget} [exec ps]]
if {$CurrentConnections > 0} {
# puts "wget is already running"
} else {
set FileName [lindex [file split $CurrentURL] end]
set lList [FileToList $::WGET_LIST]
set Out [exec head -n3 $::WGET_LOG]
set rule "^.*$FileName.*"
#Do nothing if the line is empty (this includes also empty input file)
if { "X$CurrentURL" ne "X"} {
#Let's check that log corresponds to the top line of wget.list
if {[regexp $rule $Out]} {
set Out [exec tail -n3 $::WGET_LOG]
set rule "^.*$FileName.*saved.*"
#Check if the file is completed
if {[regexp $rule $Out] || [regexp {The file is already fully retrieved; nothing to do} $Out]} {
file rename -force [file join $::WGET_PARTIAL $FileName] [file join $::WGET_COMPLETED]
for {set i 0} {$i < [llength $lList]} {incr i} {
if {[lindex $lList $i] eq $CurrentURL} {
set lList [lreplace $lList $i $i]
incr i -1
}
}
ListToFile $::WGET_LIST $lList
set f [open $::WGET_LIST_COMPLETED a]
puts $f $CurrentURL
close $f
}
#Check if URL is not found
set rule "^.*ERROR 404.*Not Found.*"
if {[regexp $rule $Out]} {
for {set i 0} {$i < [llength $lList]} {incr i} {
if {[lindex $lList $i] eq $CurrentURL} {
set lList [lreplace $lList $i $i]
incr i -1
}
}
ListToFile $::WGET_LIST $lList
set f [open $::WGET_LIST_NOT_FOUND a]
puts $f $CurrentURL
close $f
set CurrentURL ""
}
}
}
if {[llength $lList] != 0} {
set CurrentURL [lindex $lList 0]
exec $::WGET_BIN $CurrentURL --background --continue --directory-prefix=$::WGET_PARTIAL --output-file=$::WGET_LOG
# exec $::WGET_BIN $CurrentURL -b -c -P $::WGET_PARTIAL -o $::WGET_LOG
}
}
after [expr {30 * 1000}]
}
Этот скрипт сидит в оперативке и каждые 30 сек проверяет запущен ли wget. Если нет, то он запускает загрузку файла, который записан в первой строке файла /opt/tmp/wget/wget.list Первая версия использовала cron, однако, после достаточно длительного использования было обнаружено, что некоторые процессы не завершаются и остаются сидеть в памяти. Почему --- не знаю. Меня это несколько достало и я переделал этот скрипт и превратил его в демона.
второй скрипт под названием /opt/etc/init.d/S99wget запускает check.wget.tcl при перезагрузках, а также служит для запуска/остановки его вручную.
PHP Code:
#! /bin/sh
PATH=/sbin:/bin:/usr/bin:/usr/sbin:/opt/bin:/opt/sbin:/opt/local/bin
PREFIX=tclsh8.4
DAEMON=/opt/local/bin/check.wget.tcl
NAME=check.wget.tcl
start() {
echo -n "Starting $NAME... "
$DAEMON &
echo "done"
}
stop() {
echo -n "Shutting down $NAME... "
kill `pidof $PREFIX $DAEMON`
echo "done."
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
stop
sleep 1
start
;;
*)
echo "Usage: $0 (start|stop|restart)"
exit 1
;;
esac
Для работоспособности всего этого создаем вручную директории:
mkdir /opt/tmp/wget
mkdir /opt/tmp/wget/completed
mkdir /opt/tmp/wget/partial
а также делаем оба вышеуказанных файла исполняемыми:
chmod 755 /opt/local/bin/check.wget.tcl
chmod 755 /opt/etc/init.d/S99wget
Используемые файлы:
/opt/tmp/wget/wget.list : список URL-ов предназначеных к закачке. Единственный файл, который имеет смысл трогать вручную --- добавлять сюда новые URL-ы. Если надо изменить последовательность закачиваний --- меняйте местами строки в этом файле. Закачка идет последовательно сверху вниз.
/opt/tmp/wget/wget.log : процесс закачки текущего файла.
/opt/tmp/wget/wget.completed.list : список закачаных URL-ов
/opt/tmp/wget/wget.not_found.list : список ненайденных URL-ов
/opt/tmp/wget/completed : закачаные файлы
/opt/tmp/wget/partial : закачиваемые файлы
Если надо срочно загрузить что-либо, то надо прописать данный URL первым в /opt/tmp/wget/wget.list и затем убить текущий запущенный wget. После этого следующий запустится автоматом.
Наблюдается и некоторая странность --- ps показывает, что в памяти сидят 3 процесса check.wget.tcl Памяти они лишней вроде не занимают. Будем считать, что это не баг, а фича. Хотя если кто значет почему так и можно ли сделать иначе, будет любопытно узнать.
У меня все это живет уже месяца два с лишним и лично меня вполне удовлетворяет.
По этому поводу открыта новая тема http://wl500g.info/showthread.php?p=52778 , ибо здесь место не вполне удачное. Sorry, сам удивился поутру, когда обнаружил куда это дело запостил. Если будут вопросы лучше направлять туда.