I want to print out the hostname and CNAME only if DNS status is: "NXDOMAIN" OR "SERVFAIL" AND has a "CNAME".
Conditions:
dig @8.8.8.8 -t A ${hstnm} | grep -q 'NXDOMAIN'
dig @8.8.8.8 -t A ${hstnm} | grep -q 'SERVFAIL'
dig @8.8.8.8 -t CNAME $hstnm +short >/dev/null
So I wrote below bash script but it does not work, any help is very much appreciated, thank you.
for hstnm in $(cat /path/file.txt)
do
if dig @8.8.8.8 -t A ${hstnm} | grep -q 'NXDOMAIN' || dig @8.8.8.8 -t A ${hstnm} | grep -q 'SERVFAIL' && dig @8.8.8.8 -t CNAME $hstnm +short >/dev/null ]]
then
echo -n -e "\e[92mNXDOMAIN: \e[0m${hstnm} "
echo -n -e "\e[93mCNAME: \e[0m"; dig @8.8.8.8 -t CNAME $hstnm +short
echo
fi
done
OK, let's label your conditions:
dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN'
dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN'
dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL'
dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL'
dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null
Now, with those names, tell us in algorithmic language what test you want.
Also, we need to know the shell you are using (BASh? Korn? Almiquish? Z?)
Depending on these parameters, we may provide a better indication. For example
#!/bin/bash
for hstnm in $(cat /path/file.txt)
do
if ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' ) && ( dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null )
then
echo -n -e "\e[92mNXDOMAIN: \e[0m${hstnm} "
echo -n -e "\e[93mCNAME: \e[0m"; dig @8.8.8.8 -t CNAME "$hstnm" +short
echo
fi
done
assume "A or B then C"...
edit-2020-08-04 OK, what you're trying to achive is "IF (either "A" or "B" is true) and ("C" is true) THEN"
The first part, "either "A" or "B" is true" should translate to A || B
A || B
ie
if ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' )
then
#foo
fi
First, I group "A" and "B" in parentheses...or curly brackets. If I don't proceed so, I change the meaning in a bit surprising way: dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' || dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL'
dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' || dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL'
dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' || dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL'
ask the shell to
So you see why the parentheses here. But beware: bourne compatible shells don't have parenthesis for grouping logical operations like many programming languages. In fact, we're not using boolean switching but only the ability of the shell to call a command based on the success or the failure of the previous command (it's not truely-falsy system like seen elsewhere, even when using commands like test
) Despite the resemblance, parentheses group command in a subshell (use curly braces if you don't want to use a subshell and benefit some variables passing up-and-down) When the group is processed, it will have fail or succed as a bloc and have the return code of the last command run in the group.
Now, we may think about using grouping of grouping in order to achive our goals.
if { ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' ) } && ( dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null )
then
#foo
fi
Frankly, I'm don't know how shells supporte nesting grouping and will never try to found the answer if I'm not forced (you know, when you inherith a script that you have to fix...) I find that difficult to read back and hence to maintain. I prefere to go that other way:
if ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'NXDOMAIN' ) || ( dig @8.8.8.8 -t A "$hstnm" | grep -q 'SERVFAIL' )
then
if dig @8.8.8.8 -t CNAME "$hstnm" +short >/dev/null
then
#foo
fi
fi
to be followed.
This is what your post currently says (simplified):
if A || B && C ]]
then
...
fi
Simply drop the trailing ]]
.
You don't need to add any grouping, since unlike many languages, A || B && C
A || B && C
in this context in Bash is equivalent to (A || B) && C
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.