我有一个运行query.sh
命令的dig
脚本,从不同的DNS服务器执行一组查找,这些查询当前在所使用的单个输入文件的列中给出(sites.txt
)。
我的目标是修改此脚本以使用不同的输入文件dns_servers.txt
来查找要为每个查询迭代的DNS服务器。
我不知道从哪里开始。为了能够安全地嵌套while read
循环,我需要做什么?
#!/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
当前格式具有主机名和DNS服务器,用于针对该主机名进行查找。
www.google.com 8.8.4.4
意图是忽略DNS服务器的列,而改为使用dns_servers.txt
的内容。
10.1.1.1
12.104.1.232
...
答案 0 :(得分:5)
忽略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
的第二列的变量名。3
和4
)以保持它们分开。顺便提一下,如果你的目标是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