You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用parallel并行调用Bash函数批量检查30000个站点?

用GNU Parallel并行调用Bash函数批量检查站点

问题背景

我有一个用于检查30000多个站点的Bash脚本,定义了如下check_site函数:

check_site() {
  host=$1; ip=$2

  resp=$(curl -i -m1 -H "Host: $host" http://$ip 2>&1)
  echo "$resp" | grep -Eo "$ok" > /dev/null

  if [ $? -ne 0 ]; then
    echo -e "Command: curl -i -m1 -H \"Host: $host\" http://$ip 2>&1" >> "${outlog}"
    echo -e "Block failed: $host:\n\"$resp\"\n\n" >> "${outlog}"

    httpresponse=$(echo "$resp" | grep HTTP/1.1)
    echo "$host $ip $httpresponse" >> "${faillog}"
  fi
}

目前我通过check_site $host $ip的方式串行调用该函数,请问是否可以使用parallel并行调用此函数并传递$host和$ip参数?

解决方案

完全可以用GNU Parallel实现并行调用,以下是具体步骤和注意事项:

1. 导出函数和依赖变量

Parallel会启动子进程执行任务,需要先把自定义函数和函数中用到的变量导出到子进程环境:

# 导出check_site函数
export -f check_site
# 导出函数依赖的变量(根据你的脚本实际情况调整)
export ok outlog faillog

2. 选择合适的并行调用方式

根据你存储host和ip的方式,选对应的调用方法:

方式一:从文件读取配对的host和ip

如果你的host和ip已经按每行两个字段的格式存在文件(比如hosts_ips.txt)中:

# 每行对应一个host和ip,直接用-a参数指定文件
parallel -a hosts_ips.txt check_site

方式二:从数组中配对调用

如果你的host和ip分别存在两个数组hosts和ips中,用:::+保证参数一对一配对:

parallel check_site ::: "${hosts[@]}" :::+ "${ips[@]}"

方式三:通过管道传递参数

如果是通过其他命令输出获取host和ip(每行两个字段),可以用管道配合-N2指定每次取2个参数:

# 示例:假设从某个命令获取host和ip列表
generate_host_ip_list | parallel -N2 check_site

3. 控制并行进程数

默认Parallel会启动和CPU核心数相同的进程,对于30000+站点,建议根据服务器资源调整并发数,比如用-j参数指定同时运行50个进程:

parallel -j 50 -a hosts_ips.txt check_site

4. 避免日志写入冲突

高并发下多个进程同时写入日志文件可能导致内容交错,可通过flock锁定日志文件解决,修改函数中的日志写入部分:

# 修改outlog写入逻辑,加文件锁
echo -e "Command: curl -i -m1 -H \"Host: $host\" http://$ip 2>&1" | flock -x "${outlog}" -c 'cat >> "$1"' -- "${outlog}"
echo -e "Block failed: $host:\n\"$resp\"\n\n" | flock -x "${outlog}" -c 'cat >> "$1"' -- "${outlog}"

# 修改faillog写入逻辑
echo "$host $ip $httpresponse" | flock -x "${faillog}" -c 'cat >> "$1"' -- "${faillog}"

内容的提问来源于stack exchange,提问作者Marco Ferrara

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 15:43:16