如何加速批量检测网站含指定内容的Bash脚本?
提速方案
原脚本慢的核心原因是串行执行每个curl请求,一个请求完成才会开始下一个,针对这个问题可以从并行执行、curl参数优化两个方向入手:
一、并行处理请求
直接把多个请求丢到后台同时跑,是最有效的提速手段,这里给几种实现方式:
1. 用bash后台进程+wait(无需额外工具)
把每个检测任务放到后台执行,最后等待所有任务完成,同时用临时文件避免输出混乱:
scan_list() { # 创建临时目录存单个任务的输出 local tmpdir=$(mktemp -d) # 用while read读取文件,避免域名含空格的问题 while read -r url; do ( if curl -skL --connect-timeout 3 -m 5 "$url" | grep -q -m1 "Hello World!"; then echo "$url Hello World!" else echo "$url No Hello:(" fi ) > "${tmpdir}/${url//\//_}.out" & # 替换斜杠避免路径问题 done < "$list" wait # 等所有后台进程结束 cat "${tmpdir}"/*.out # 汇总输出 rm -rf "${tmpdir}" # 清理临时文件 }
2. 用xargs快速实现并行(系统自带)
xargs的-P参数可以指定同时运行的进程数,比如-P10就是同时跑10个请求:
scan_list() { # 并行数按需调整,比如10、15 local parallel_num=10 xargs -P"${parallel_num}" -I{} bash -c ' if curl -skL --connect-timeout 3 -m 5 "{}" | grep -q -m1 "Hello World!"; then echo "{} Hello World!" else echo "{} No Hello:(" fi ' < "$list" }
3. 用GNU Parallel(如果已安装)
Parallel是专门的并行工具,语法更灵活,适合复杂场景:
scan_list() { parallel -j15 ' if curl -skL --connect-timeout 3 -m 5 {} | grep -q -m1 "Hello World!"; then echo "{} Hello World!" else echo "{} No Hello:(" fi ' < "$list" }
二、优化curl参数,减少不必要的等待和传输
原脚本没有设置超时,遇到无响应的网站会一直挂着,而且会下载整个页面,这两个点都能优化:
--connect-timeout 3:限制连接超时为3秒-m 5:限制整个请求的总超时为5秒grep -q -m1:找到第一个"Hello World!"就停止匹配,curl也会跟着终止传输,不用下载完整页面
三、其他小细节优化
- 用
while read -r url代替for run in $(cat $list):后者遇到域名含空格会出错,前者更健壮 - 用
grep -q代替[[ ... =~ ... ]]:grep是专门的文本匹配工具,效率更高,还不用把整个页面加载到内存里
最后给个组合优化后的完整脚本:
#!/bin/bash put() { printf "list : " read -r list } put scan_list() { local parallel_num=15 xargs -P"${parallel_num}" -I{} bash -c ' url="{}" if curl -skL --connect-timeout 3 -m 5 "$url" | grep -q -m1 "Hello World!"; then echo "$url Hello World!" else echo "$url No Hello:(" fi ' < "$list" } scan_list
内容的提问来源于stack exchange,提问作者bintaaaaang
相关产品推荐
相关产品推荐

