我正在尝试编写一个bash脚本,该脚本将为我提供区域文件中链接CNAME记录的文件输出。我设法只创建了一个步骤链(cname1 CNAME cname2 - > cname2 - >某些A记录)。
如果中间有多个步骤,我要做的就是打印整个链。
链A A 10.100.250.22
chainB CNAME chainA
chainC CNAME chainB
chainD CNAME chainC
我希望输出如下: chainD - > chainC - > chainB - > chainA是A记录。
到目前为止,我将所有的cnames提取到一个文件中,并将while循环遍历它们,但它只找到一步:
#!/bin/bash
read -e -p "Enter filename (use tab for completion): " file
ls -l "$file"
date=$(date +%m_%d_%y)
echo $date
if [ -f chained_cnames_$date ] ; then
rm chained_cnames_$date
fi
grep -w "CNAME" $file | grep "^[^#;]" > cnames_out
while IFS='' read -r line || [[ -n "$line" ]]
do
echo "Scanning record: $line"
name=$(echo $line | awk '{print $1}' | sed 's/[.].*$//' | awk '{$1=$1};1')
dst=$(echo $line | awk '{print $3}' | sed 's/[.].*$//' | awk '{$1=$1};1')
dst_long=$(echo $line | awk '{print $3}')
dst_long_a=$(dig +noall +answer $dst_long | awk '{print $1}')
if [ "$name" = "$dst" ]
then
ipaddr="$(dig $dst_long +short)"
if [ -z "$ipaddr" ]
then
echo $line " ---> " "NO A RECORD" >> chained_cnames_$date
else
echo $line " ---> " $ipaddr " A record exists, but is not in this zone file.\n It should be like:\n $name CNAME $dst_long_a" >> chained_cnames_$date
fi
else
while IFS='' read -r line1 || [[ -n "$line1" ]]
do
testrec=$(echo $line1 | awk '{print $1}' | awk '{$1=$1};1')
if [ "$dst" = "$testrec" ]
then
echo >> chained_cnames_$date
echo $line " ---> " $line1 >> chained_cnames_$date
echo >> chained_cnames_$date
fi
done < "cnames_out"
fi
done < "cnames_out"
echo
echo
echo "Done! Invalid records are stored in the chained_cnames_$date file."
rm cnames_out
如何创建这样的循环?
答案 0 :(得分:1)
这很有趣,
% cat cNamePath.sh
#!/bin/bash
# chainA A 10.100.250.22
# chainB CNAME chainA
# chainC CNAME chainB
# chainD CNAME chainC
awk '
NR!=1{print $1 " " $3}
' ./testDat.raw | {
tsort | tr '\n' ' '
# process inFile a 2nd time, just to grab the first record
# this could be simplified to just a `print` statment, do you see how? ;-)
awk 'NR==1{base=$1;skip=$2;ip=$3;print base " is A record"}' ./testDat.raw
}
% chmod +x cNamePath.sh
<强>输出强>
chainD chainC chainB chainA chainA is A record
如果你确实需要->
的输出,我相信你可以弄清楚如何获得它。
此外,您还需要参数化文件名中的传递。
要了解代码是如何工作的,请执行第一个“pipe-full”,然后添加另一个部分,另一个部分等。
结束| { tsort ... ; awk ..; }
被称为一个进程组(由匹配的对{ ..}
表示。你使用它来使所有输出“折叠在一起”并传递给相同的“目标”。如果你想要的话要将输出重定向到文件,使用进程组使其变得非常简单,即...| {tsort ... ; awk ...;} > outFile
(我包含一个;
字符,以显示cmd是独立的,并且不会在管道中发送到跟随cmd。它不包含在代码中,因为tsort
行和nawk
行功能之间的换行方式与;
相同,只需一行。(TMI) ?)
如果您不了解tsort
,请查看此linux tsort on Wikipedia文章。
tsort
的美妙之处在于它会为你找出关系的顺序,你不需要你提供的“排序”文件。它可以轻松地订购数据,如
chainA A 10.100.250.22
chainD CNAME chainC
chainC CNAME chainB
chainB CNAME chainA
IHTH