如何用原生Bash实现LAN内IP的多线程FQDN查询提速?
原生Bash实现局域网IP多线程FQDN查询优化
问题描述
现有一段单线程Bash脚本,用于遍历局域网内IP地址并查询对应FQDN,即使给Python查询命令加上0.3秒超时,整体执行耗时仍不符合预期。需要将IP查询与主机名匹配的逻辑改为原生Bash并发执行,不能依赖额外安装的工具。
原单线程核心逻辑:
while [[ $ws -le $total_ip ]]; do ip="${ip_range}.${ws}" machine=$(timeout 0.3s python3 -c "import socket; print(socket.getfqdn('$ip'))") if[[ "$machine" = "$myMachine" ]]; then my_ip=$ip break fi done
解决方案:Bash并发实现
Bash没有原生线程,但可以通过**后台进程(&)**结合进程管理实现并发,同时控制并发数避免资源过载,找到目标IP后立即终止所有任务。
优化后的完整代码
# 配置并发数(根据网络环境调整,比如20) MAX_CONCURRENT=20 found_ip="" # 单个IP的查询逻辑,作为后台进程执行 query_ip() { local ip="$1" local target="$2" # 执行FQDN查询,超时0.3秒 local machine=$(timeout 0.3s python3 -c "import socket; print(socket.getfqdn('$ip'))") # 匹配成功则写入临时文件,并通知主进程 if [[ "$machine" = "$target" ]]; then echo "$ip" > /tmp/found_ip.tmp kill -s USR1 $$ fi } # 捕获USR1信号:获取结果、清理进程并退出 trap ' found_ip=$(cat /tmp/found_ip.tmp) rm -f /tmp/found_ip.tmp pkill -P $$ exit 0 ' USR1 # 遍历IP并启动并发任务 ws=1 while [[ $ws -le $total_ip ]]; do # 控制并发数:后台进程数达到上限时等待 while [[ $(jobs -r | wc -l) -ge $MAX_CONCURRENT ]]; do sleep 0.05 done ip="${ip_range}.${ws}" query_ip "$ip" "$myMachine" & ws=$((ws+1)) done # 等待剩余任务完成(如果没提前找到结果) wait # 清理临时文件并赋值结果 rm -f /tmp/found_ip.tmp if [[ -n "$found_ip" ]]; then my_ip="$found_ip" else echo "未找到匹配的主机IP" fi
关键细节说明
- 并发数控制:通过
jobs -r | wc -l统计运行中的后台进程数,超过MAX_CONCURRENT时短暂等待,防止同时发起过多请求导致网络阻塞。 - 结果安全捕获:用临时文件存储匹配到的IP,避免多进程直接修改全局变量引发的竞争问题;通过
USR1信号立即通知主进程终止所有子任务。 - 即时终止:一旦找到目标IP,主进程通过
pkill -P $$杀死所有子进程,无需等待剩余任务执行完成,最大化节省时间。 - 原生兼容性:所有操作均使用Bash内置命令和标准工具,无需额外安装软件。
内容的提问来源于stack exchange,提问作者Young Fellow
相关产品推荐
相关产品推荐

