0

I am trying to make a bash script that shows me the domains MX-es of one or more domains given as arguments when running it. Example script call:

./domains.sh domain1.com domain-no-mx.com domain2.net domain3.io

The expected output is each domain with a : followed by their MX-es - each on a new line and to make it readable 2 spaces at the beginning of each MX. If there is no MX, just output the domain Example output:

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

This is what I got so far:

#!/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

It works with one domain (except the thing with the 2 spaces at the beginning of each MX) but it repeats the MX-es when giving multiple domains (arguments). I'm really struggling with the output and also with the details. I also tried with a second for loop and array (commented it out). As you can see, I'm rather a beginner and would be happy to get some inputs here :)

Thank you so much, greetings Marco

2
  • 1
    if you do for domain in "$@" then domain gets each of the command line arguments in turn. You probably want to then use that for dig, not $@ again.
    – ilkkachu
    Aug 7, 2021 at 20:53
  • Am I correct in thinking that you are trying to extract the MX records from a DNS lookup? Aug 7, 2021 at 21:54

1 Answer 1

1

There's no reason to store things in arrays or variables of any type. You are also including $@ in each dig query in your loop.

Here's my take on your exercise:

#!/bin/sh

for domain do
        dig "$domain" mx +short |
        awk -v domain="$domain" 'BEGIN { print domain } { printf "\t%s\n", $2 }'
done

This indents by a tab, but that's easy to change.

The body of the loop calls dig and passes the output directly to awk which takes care of all output, printing the domain itself in the BEGIN block, and then second column from the dig output indented with a tab character.

Example run:

$ ./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.

Instead of the awk code, you could obviously do something more like what you're already doing and print the doamin at the start of each iteration and then make sure to output the rest of the output indented. Here I've decided to replace the start of each line of output from dig (the bit up to the space) by two spaces.

#!/bin/sh

for domain do
        printf '%s\n' "$domain"
        dig "$domain" mx +short | sed 's/.* /  /'
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .