如何在Bash循环中实现多线程并行Curl请求及补零问题解决
搞定curl批量请求的两个问题:前导零丢失+提速并行
一、先解决前导零丢失的坑
直接用{0000001..0000100}在脚本里执行时,部分shell(比如sh)会把带前导零的数字当成八进制数处理,导致前导零直接丢失。靠谱的做法是用printf格式化数字,保证生成固定长度的带前导零字符串:
方案1:printf配合for循环
for i in {1..100}; do user_num=$(printf "%07d" $i) # 把1转换成0000001,固定7位长度 curl --retry 20 --retry-on-http-error 5xx 'http://example.com/Services/ServiceWS' \ -H 'Accept: */*' \ -H 'Accept-Language: en-US,en;q=0.9' \ -H 'Content-Type: text/xml; charset=UTF-8' \ --data-raw "User${user_num}" \ --insecure \ --output "User${user_num}.output" done
方案2:用seq直接生成带前导零的序列
如果你的系统自带GNU seq,直接用seq -w就能生成带前导零的连续数字:
for user_num in $(seq -w 1 100); do curl --retry 20 --retry-on-http-error 5xx 'http://example.com/Services/ServiceWS' \ -H 'Accept: */*' \ -H 'Accept-Language: en-US,en;q=0.9' \ -H 'Content-Type: text/xml; charset=UTF-8' \ --data-raw "User${user_num}" \ --insecure \ --output "User${user_num}.output" done
二、改成多线程并行,提速明显
方案1:Bash后台任务+手动控并发
给curl命令加&丢到后台运行,但要控制并发数,避免一下子发太多请求压垮服务器:
max_concurrent=10 # 最多同时跑10个请求,可根据服务器情况调整 count=0 for i in {1..100}; do user_num=$(printf "%07d" $i) curl --retry 20 --retry-on-http-error 5xx 'http://example.com/Services/ServiceWS' \ -H 'Accept: */*' \ -H 'Accept-Language: en-US,en;q=0.9' \ -H 'Content-Type: text/xml; charset=UTF-8' \ --data-raw "User${user_num}" \ --insecure \ --output "User${user_num}.output" & count=$((count+1)) if [ $count -ge $max_concurrent ]; then wait # 等当前这批后台任务跑完再继续 count=0 fi done wait # 等最后一批任务收尾
方案2:用xargs实现并行
xargs的-P参数可以直接指定并发数,系统一般都自带,用起来很方便:
seq 1 100 | xargs -I {} -P 10 bash -c ' user_num=$(printf "%07d" {}) curl --retry 20 --retry-on-http-error 5xx "http://example.com/Services/ServiceWS" \ -H "Accept: */*" \ -H "Accept-Language: en-US,en;q=0.9" \ -H "Content-Type: text/xml; charset=UTF-8" \ --data-raw "User${user_num}" \ --insecure \ --output "User${user_num}.output" '
-P 10表示同时运行10个进程,-I {}用来替换seq生成的每个数字。
方案3:GNU parallel(需提前安装)
如果你的系统装了GNU parallel,语法更简洁,适合复杂批量任务:
parallel -j 10 ' user_num=$(printf "%07d" {}) curl --retry 20 --retry-on-http-error 5xx "http://example.com/Services/ServiceWS" \ -H "Accept: */*" \ -H "Accept-Language: en-US,en;q=0.9" \ -H "Content-Type: text/xml; charset=UTF-8" \ --data-raw "User${user_num}" \ --insecure \ --output "User${user_num}.output" ' ::: {1..100}
-j 10指定并发数,::: {1..100}是要处理的数字序列。
关于curl重试的补充
- 如果你的curl版本低于7.71.0,没有
--retry-on-http-error参数,可以用--retry-all-errors让curl重试所有错误(包括5xx),但注意这也会重试4xx这类客户端错误,需根据需求调整。 --retry 20是最多重试20次,默认每次间隔1秒,要是怕请求太频繁,可以加--retry-delay N设置每次重试间隔N秒。
内容的提问来源于stack exchange,提问作者Zeronito
相关产品推荐
相关产品推荐

