我正在尝试制作一个 bash 脚本,该脚本向我显示运行时作为参数给出的一个或多个域的 MX-es。脚本调用示例:
./domains.sh domain1.com domain-no-mx.com domain2.net domain3.io
预期的输出是每个域都有一个 : 后跟它们的 MX-es - 每个域都在一个新行上,并使其在每个 MX 开头有 2 个空格可读。如果没有 MX,则只输出域示例输出:
domain1.com:
mx1.domain1.com
mx2.domain1.com
domain-no-mx.com:
domain2.net:
mx1.domain2.net
mx2.domain2.net
domain3.io:
mx1.domain3.io
这是我到目前为止得到的:
#!/bin/bash
# Check if at least one domain (argument) has been given
if [ $# = 0 ]; then
echo "usage: $(basename $0) list-of-domains" 1>&2
exit 1
fi
for domain in "$@"
do
echo "$domain:"
MX=$(dig $@ MX +short | cut -d " " -f 2)
printf '%s\n' " ${MX[@]}"
# for (( i=0; i<${#arr[@]}; i++));
# do
# echo " ${arr[i]}"
# done
done
它适用于一个域(每个 MX 开头有 2 个空格的情况除外),但在给出多个域(参数)时它会重复 MX-es。我真的很挣扎于输出和细节。我还尝试了第二个 for 循环和数组(将其注释掉)。正如你所看到的,我是一个初学者,很乐意在这里得到一些意见:)
非常感谢你,问候马可
答案1
没有理由将内容存储在任何类型的数组或变量中。您还包括在循环中的$@
每个查询中。dig
这是我对你的练习的看法:
#!/bin/sh
for domain do
dig "$domain" mx +short |
awk -v domain="$domain" 'BEGIN { print domain } { printf "\t%s\n", $2 }'
done
这会缩进一个制表符,但这很容易更改。
循环体调用输出dig
并将其直接传递给awk
它来处理所有输出,在BEGIN
块中打印域本身,然后dig
使用制表符缩进输出的第二列。
运行示例:
$ ./script kth.se uu.se
kth.se
mx-alt1.kth.se.
mx.kth.se.
uu.se
mailfilter-ng-3.sunet.se.
mailfilter-ng-1.sunet.se.
mailfilter-ng-2.sunet.se.
除了awk
代码之外,您显然可以做一些更像您已经在做的事情,并在每次迭代开始时打印 doamin,然后确保输出缩进的其余输出。在这里,我决定将每行输出的开头dig
(从位到空格)替换为两个空格。
#!/bin/sh
for domain do
printf '%s\n' "$domain"
dig "$domain" mx +short | sed 's/.* / /'
done