Bash:循环多个输入源(嵌套 "while read"循环?)

标签 bash

我有一个 query.sh 脚本,它运行 dig 命令,从不同的 DNS 服务器执行一组查找,目前在单个输入的一列中给出使用的文件 (sites.txt)。

我的目标是修改此脚本以使用不同的输入文件 dns_servers.txt 来查找 DNS 服务器以针对每个查询进行迭代。

我不清楚从哪里开始。我需要做什么才能安全地嵌套 while read 循环?


当前输入:

查询.sh

#!/bin/sh

while read line;
do
        set $line
        echo "SITE:" $1@$2
        /usr/sbin/dig +short -4 @$2 $1
        sleep 5
        exitStatus=$?
        echo "Exit Status: " $exitStatus
done < sites.txt

网站.txt

当前格式有一个主机名和一个用于查找该主机名的 DNS 服务器。

www.google.com 8.8.4.4

目的是忽略包含 DNS 服务器的列,而是使用 dns_servers.txt 的内容。


所需的输入

dns_servers.txt

10.1.1.1
12.104.1.232
...

最佳答案

忽略 sites.txt 文件中的任何其他列,并遍历 dns_servers.txt 的行,可能如下所示:

#!/bin/sh
while read -r site _ <&3; do
  while read -r dns_server <&4; do
    dig +short -4 "@$dns_server" "$site"; exit=$?
    sleep 5
    echo "Exit status: $exit"
  done 4<dns_servers.txt
done 3<sites.txt

这里的关键变化:

  • 将要解析的字段列表作为参数传递给read。作为第二个位置参数传递给第一个 read 的下划线是现在保存 site.txt 第二列的变量名。
  • 嵌套您的循环,因为您希望在每次通过外循环时都从内循环读取数据。
  • 为外循环和内循环使用不同的文件描述符(此处为 34)以将它们分开。

顺便说一下,如果您的目标是 bash (#!/bin/bash) 而不是 POSIX sh (#!/bin/sh),我可能会采取不同的方式.下面使用 bash 4 扩展 mapfile 一次性读取 dns_servers.txt:

#!/bin/bash
readarray -t dns_servers <dns_servers.txt
while read -r site _; do
  for from_ip in "${dns_servers[@]}"; do
    dig +short -4 "@$from_ip" "$site"; exit=$?
    sleep 5
    echo "Exit status: $exit"
  done
done <sites.txt

在这里,我们只读取一次 dns_servers.txt,然后为从 sites.txt 读取的每个值重复使用该值列表。

如果您使用的是 bash 3.x,mapfile 可以替换为循环:

dns_servers=( )
while read -r; do dns_servers+=( "$REPLY" ); done <dns_servers.txt

关于Bash:循环多个输入源(嵌套 "while read"循环?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31791324/

相关文章:

bash - 如何在 awk 脚本中使用 shell 变量?

linux - 如何使用 sed 命令交换两个字符串,分隔符是逗号?

bash - 如何在 shell 脚本中制作动画?

bash - grep 多个文件

git:检查上次获取运行的时间

arrays - 使用 bash 在数组中旋转值

Bash-当我试图得到 16 的平方时,这是错误的

linux - 编辑器中的终端编辑命令

linux - Linux Shell脚本中for循环的语法

bash - 在 bash 中进行并行处理?