Dê uma olhada em man xargs :
-P max-procs --max-procs=max-procsRun up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time.
Solução:
xargs -P 20 -n 1 wget -nv <urs.txt
Digamos que eu tenha um arquivo com muitos URLs e eu queira baixá-los em paralelo usando um número arbitrário de processos. Como posso fazer isso com o bash?
Dê uma olhada em man xargs :
-P max-procs --max-procs=max-procsRun up to max-procs processes at a time; the default is 1. If max-procs is 0, xargs will run as many processes as possible at a time.
Solução:
xargs -P 20 -n 1 wget -nv <urs.txt
Se você quiser apenas pegar cada URL (independentemente do número), a resposta é fácil:
#!/bin/bash
URL_LIST="http://url1/ http://url2/"
for url in $URL_LIST ; do
wget ${url} & >/dev/null
done
Se você quiser apenas criar um número limitado de pulls, digamos 10. Então você faria algo assim:
#!/bin/bash
URL_LIST="http://url1/ http://url2/"
function download() {
touch /tmp/dl-${1}.lck
wget ${url} >/dev/null
rm -f /tmp/dl-${1}.lck
}
for url in $URL_LIST ; do
while [ 1 ] ; do
iter=0
while [ $iter -lt 10 ] ; do
if [ ! -f /tmp/dl-${iter}.lck ] ; then
download $iter &
break 2
fi
let iter++
done
sleep 10s
done
done
Observe que eu não testei, mas acabei de bater em 15 minutos. mas você deve ter uma ideia geral.
Você pode usar algo como puf projetado para esse tipo de coisa, ou usar wget / curl / lynx em combinação com o paralelo GNU .
link puf faz isso "para viver" e tem um bom status de execução do processo completo.
I do stuff like this a lot. I suggest two scripts.
the parent only determines the appropriate loading factors and
launches a new child when there is
1. more work to do
2. not past some various limits of loadavg or bandwidth
# my pref lang is tcsh so, this is just a rough approximation
# I think with just a few debug runs, this could work fine.
# presumes a file with one url to download per line
#
NUMPARALLEL=4 # controls how many at once
#^tune above number to control CPU and bandwidth load, you
# will not finish fastest by doing 100 at once.
# Wed Mar 16 08:35:30 PDT 2011 , dianevm at gmail
while : ; do
WORKLEFT='wc -l < $WORKFILE'
if [ WORKLEFT -eq 0 ];
echo finished |write sysadmin
echo finished |Mail sysadmin
exit 0
fi
NUMWORKERS='ps auxwwf|grep WORKER|grep -v grep|wc -l'
if [ $NUMWORKERS -lt $NUMPARALLEL]; then # time to fire off another 1
set WORKTODO='head -1 $WORKFILE'
WORKER $WORKTODO & # worker could just be wget "$1", ncftp, curl
tail -n +2 $WORKFILE >TMP
SECEPOCH='date +%s'
mv $WORKFILE $WORKFILE.$SECSEPOCH
mv TMP $WORKFILE
else # we have NUMWORKERS or more running.
sleep 5 # suggest this time be close to ~ 1/4 of script run time
fi
done