Search code examples
bashscriptingdig

Printing specific elements from dig, using bash


I'm trying to write a bash script that digs MX on some sites from a list.
I don't need all the redundant information besides what MX the domain has.

So far this is what my script looks like:

#! /bin/bash


{ while IFS=';' read un fake
do
        dig mx $un >> tmp.txt
        awk -F ';' ' {print $1}' tmp.txt >> mxinfo.txt

done
} <mxlist.txt

mxlist.txt:

vg.no;
godaddy.com;
finn.no;

The output I get from this is full of empty space an a whole line.

And I would like it to print it like this:

vg.no = ASPMX.L.GOOGLE.COM
vg.no = ALT1.ASPMX.L.GOOGLE.COM
vg.no = ALT2.ASPMX.L.GOOGLE.COM
vg.no = ALT3.ASPMX.L.GOOGLE.COM
godaddy.com = godaddy-com.mail.protection.outlook.com
finn.no = alt2.aspmx.l.google.com
finn.no = aspmx.l.google.com
finn.no = alt1.aspmx.l.google.com
finn.no = alt4.aspmx.l.google.com
finn.no = alt3.aspmx.l.google.com

Also you see that some queries appear twice or more.
How can I write this better without the extra spacing, redundant info and just one output per domain?


Solution

  • What about just using host, like this:

    $ host -t mx vg.no
    vg.no mail is handled by 5 ALT1.ASPMX.L.GOOGLE.COM.
    vg.no mail is handled by 10 ALT4.ASPMX.L.GOOGLE.COM.
    vg.no mail is handled by 1 ASPMX.L.GOOGLE.COM.
    vg.no mail is handled by 10 ALT3.ASPMX.L.GOOGLE.COM.
    vg.no mail is handled by 5 ALT2.ASPMX.L.GOOGLE.COM.
    

    ...But lets work on your script. The first problem I see is that for each domain, you append the dig output to tmp.txt, and then process that. But that means that when it handles the second domain, the dig output from the first domain is still in tmp.txt (it was appended to, rather than replaced), so it gets processed again. And then again on the third iteration, the first and second domains are still there, so both of them get processed again, etc.

    Solution: either use a single > (i.e. > tmp.txt) to replace the contents directly, or just skip the temp file and pipe the output directly to awk (or whatever's next).

    The second problem is that the awk command, awk -F ';' ' {print $1}', is just printing everything before the first ";" on each line. It prints that even on lines that start with semicolons, or are just blank; in both cases, it prints blank lines. So you get a lot of blank lines in your output. Also, on the lines that do have relevant content, it doesn't remove all the extra data besides the MX domain itself:

    vg.no.          300 IN  MX  1 ASPMX.L.GOOGLE.COM.
    vg.no.          300 IN  MX  10 ALT4.ASPMX.L.GOOGLE.COM.
    ...
    

    You could fix the awk script to remove the blank lines and irrelevant data, but it'd be way simpler to use dig +short to just skip the irrelevant bits:

    $ dig +short mx vg.no
    5 ALT2.ASPMX.L.GOOGLE.COM.
    1 ASPMX.L.GOOGLE.COM.
    10 ALT4.ASPMX.L.GOOGLE.COM.
    5 ALT1.ASPMX.L.GOOGLE.COM.
    10 ALT3.ASPMX.L.GOOGLE.COM.
    

    To get the output in the form in your example, you just need a short awk program to remove the priority field and prefix the domain name being looked up:

    $ un=vg.no
    $ dig +short mx "$un" | awk -v un="$un" '{print un " = " $2}'
    vg.no = ASPMX.L.GOOGLE.COM.
    vg.no = ALT4.ASPMX.L.GOOGLE.COM.
    vg.no = ALT1.ASPMX.L.GOOGLE.COM.
    vg.no = ALT3.ASPMX.L.GOOGLE.COM.
    vg.no = ALT2.ASPMX.L.GOOGLE.COM.
    

    Note that the MX records aren't in any particular order; if you want them sorted by priority, add sort -g into the pipeline between dig and awk.