0

Shell脚本curl重定向检测并行加速方法:3种方案让批量巡检速度快10倍

2026.06.04 | youres | 20次围观

前言:串行检测太慢?你需要并行

当你用curl逐个检测几十上百个URL的重定向状态时,串行执行(一个接一个)的效率让人抓狂。假设每个请求平均耗时0.5秒,100个URL就是50秒。如果加上重定向跟随和网络延迟,时间可能翻倍。本文介绍3种Shell脚本并行加速方案,从最简单的xargs到专业的GNU Parallel,让你批量重定向检测速度提升10倍以上。

方案一:xargs -P 并行执行

基本用法

xargs是Linux系统自带的工具,-P参数可以指定并行数量。这是最轻量级的并行方案,不需要安装额外软件:

cat urls.txt | xargs -P 10 -I {} curl -s -o /dev/null -w "%{url_effective} %{http_code} %{num_redirects}\n" -L -m 10 "{}"

参数说明:

  • -P 10:同时执行10个curl进程
  • -I {}:将每个URL替换到命令中的占位符
  • -L:跟随重定向
  • -m 10:每个请求最长10秒超时

输出格式化到CSV

实际巡检中,我们需要把结果保存到文件。xargs并行执行时输出顺序会乱,所以需要在输出中包含URL信息:

cat urls.txt | xargs -P 20 -I {} sh -c 'curl -s -o /dev/null -w "{} %{url_effective} %{http_code} %{num_redirects} %{time_total}\n" -L -m 10 "{}"' > redirect_check.csv

xargs方案的优缺点

  • 优点:系统自带,无需安装;语法简单;适合中小规模(几十到几百个URL)
  • 缺点:输出顺序不可控;无法方便地控制并发速率(容易打满目标服务器);错误处理能力弱

方案二:GNU Parallel 专业并行控制

安装与基本用法

GNU Parallel是专门为命令行并行设计的工具,功能远比xargs强大。大多数Linux发行版可以直接安装:

# Debian/Ubuntu
sudo apt install parallel

# CentOS/RHEL
sudo yum install parallel

# macOS
brew install parallel

基本用法和xargs类似,但提供了更多控制选项:

cat urls.txt | parallel -j 20 'curl -s -o /dev/null -w "{} %{url_effective} %{http_code} %{num_redirects}\n" -L -m 10 {}'

限速控制:避免打满目标服务器

批量检测时最怕的就是把目标服务器压垮。GNU Parallel提供了优雅的限速机制:

# 每秒最多发起5个新请求
cat urls.txt | parallel --delay 0.2 -j 20 'curl -s -o /dev/null -w "{} %{url_effective} %{http_code}\n" -L -m 10 {}'

--delay 0.2表示每个请求之间间隔0.2秒(每秒5个),-j 20表示最大并发20个。两个参数配合,既能保持高并发又不会瞬间打满连接。

进度条和结果汇总

cat urls.txt | parallel --progress -j 20 --joblog redirect.log \
  'curl -s -o /dev/null -w "{} %{url_effective} %{http_code} %{num_redirects} %{time_total}\n" -L -m 10 {}' > redirect_check.csv
  • --progress:显示进度条和ETA
  • --joblog redirect.log:记录每个任务的执行状态、退出码、耗时到日志文件

GNU Parallel的优缺点

  • 优点:限速控制精细;进度显示和日志记录完善;支持断点续跑;支持SSH远程并行
  • 缺点:需要额外安装;学习曲线略陡;某些精简Linux发行版默认不带

方案三:后台任务+wait批量并行

纯Bash实现

如果你不想安装任何额外工具,纯Bash也能实现并行。原理是利用&把任务放到后台,然后用wait等待全部完成:

#!/bin/bash
MAX_CONCURRENT=15
RUNNING=0

while IFS= read -r url; do
    curl -s -o /dev/null \
      -w "${url} %{url_effective} %{http_code} %{num_redirects} %{time_total}\n" \
      -L -m 10 "${url}" >> redirect_check.csv &
    
    RUNNING=$((RUNNING + 1))
    if [ $RUNNING -ge $MAX_CONCURRENT ]; then
        wait -n
        RUNNING=$((RUNNING - 1))
    fi
done < urls.txt

# 等待所有剩余任务完成
wait
echo "全部完成"

这个脚本的核心逻辑:wait -n会等待任意一个后台任务完成,然后释放一个并发槽位。这样始终维持15个curl同时运行。

超时保护

加一层超时保护更稳妥,防止个别慢请求卡住整个流程:

timeout 15 curl -s -o /dev/null \
  -w "${url} %{url_effective} %{http_code} %{num_redirects}\n" \
  -L -m 10 "${url}" >> redirect_check.csv &

纯Bash方案的优缺点

  • 优点:零依赖,任何Bash环境都能跑;逻辑透明,便于定制;适合嵌入到现有脚本中
  • 缺点:没有进度显示;错误处理需要自己写;并发控制不如GNU Parallel精细

三种方案对比

特性xargs -PGNU Parallel纯Bash
安装要求系统自带需安装系统自带
并发控制基础精细(限速/延迟)中等
进度显示
执行日志有(--joblog)需自行实现
断点续跑不支持支持需自行实现
适合规模几十到几百几百到上万几十到几百
学习成本

实用建议

  • 并发数不是越大越好:建议从10开始测试,观察目标服务器响应情况和本机CPU/内存占用,逐步调高
  • 一定要加超时-m 10--connect-timeout 5,避免单个慢请求拖住整个流程
  • 结果包含原始URL:并行执行时输出顺序不可预测,每行输出必须带上原始URL才能对应分析
  • 分批执行:URL数量超过1000时,建议按域名分组分批检测,避免集中请求单一服务器
  • 配合sort去重:检测完成后用sort -u处理结果,消除重复记录

延伸阅读

如果你想进一步了解curl重定向检测的基础知识和单个命令的用法,可以参考以下文章:

版权声明

本文仅代表个人观点。
本文系AI辅助作者原创,未经许可,转载请保留原文链接。

发表评论