并行wget在Bash中
我从网站上得到了一堆相对较小的页面,并想知道我是否可以以某种方式在Bash中并行执行此操作。 目前我的代码看起来像这样,但执行需要一段时间(我认为是什么让我放慢了连接的延迟)。
for i in {1..42} do wget "https://www.example.com/page$i.html" done
我听说过使用xargs,但是我不知道这些,手册页非常混乱。 有任何想法吗? 甚至可以同时做到这一点? 有什么办法可以去攻击这个吗?
更喜欢使用&
或-b
将wget
推入背景,您可以使用xargs
来达到同样的效果,而且更好。
好处是xargs
将会正确同步 ,而不需要额外的工作。 这意味着您可以安全地访问下载的文件(假设没有错误发生)。 一旦xargs
退出,所有下载都将完成(或失败),并且您通过退出代码知道是否一切顺利。 这对于忙于等待sleep
和手动完成testing来说是非常可取的。
假设URL_LIST
是一个包含所有URL的variables(可以在OP的例子中用一个循环来构build,但也可以是一个手动生成的列表),运行如下:
echo $URL_LIST | xargs -n 1 -P 8 wget -q
会一次传递一个参数( -n 1
)到wget
,并且一次最多执行8个并行wget
进程( -P 8
)。 xarg
在最后产生的过程完成后返回,这正是我们想知道的。 没有额外的欺骗需要。
我select的8个并行下载的“神奇数字”并不是一成不变的,但它可能是一个很好的折衷。 “最大化”一系列下载有两个因素:
一个是填充“电缆”,即利用可用带宽。 假设“正常”条件(服务器比客户端具有更多的带宽),这已经是一次或最多两次下载的情况。 在这个问题上抛出更多的连接只会导致数据包被丢弃,TCP拥塞控制踢入, N个下载以渐近的1 / N的带宽,达到相同的净效果(减去丢包,减去窗口大小恢复)。 被丢弃的数据包在IPnetworking中是正常的事情,这就是拥塞控制应该如何工作(即使是单一的连接),通常影响几乎为零。 但是,如果有不合理的连接数量会放大这个效应,所以可能会引起注意。 无论如何,它并没有让事情变得更快。
第二个因素是连接build立和请求处理。 在这里,在飞行中有一些额外的连接确实有帮助 。 所面临的问题是两次往返的延迟(通常在同一地理区域内20-40毫秒,大陆间200-300毫秒)加上服务器实际需要处理请求并推回答的奇数1-2毫秒到sockets。 这本身并不是很多时间,但乘以几百/千的请求,很快就会加起来。
从半打到十几个请求正在进行的任何事情都隐藏了这个延迟的大部分或全部(它仍然存在,但由于它重叠,所以不能总结)。 同时,只有less量并发连接不会造成不利影响,例如造成过度拥塞,或者迫使服务器分出新的进程。
只是在后台运行这个工作并不是一个可扩展的解决scheme:如果你正在获取10000个URL,你可能只想并行获取几个(比如说100个)。 GNU并行是为了这个:
seq 10000 | parallel -j100 wget https://www.example.com/page{}.html
有关更多示例,请参见手册页: http : //www.gnu.org/software/parallel/man.html#example__download_10_images_for_each_of_the_past_30_days
你可以使用-b
选项:
wget -b "https://www.example.com/page$i.html"
如果您不想要日志文件,请添加选项-o /dev/null
。
-o将FILE日志消息发送到FILE。
为命令添加&符号使其在后台运行
for i in {1..42} do wget "https://www.example.com/page$i.html" & done
wget的版本2似乎实现了多个连接。 github中的项目链接: https : //github.com/rockdaboot/wget2