10

I wrote a little Bash script, that uses spfquery for checking upon my domain email SPF record, if it passes on all providers IP addresses:

#!/bin/bash

# RED="\033[1;31m"
GREEN="\033[1;32m"
NOCOLOR="\033[0m"

email="[my email address]" # deleted for bots not to hound me

declare -a ips=("88.86.120.212" "88.86.120.223" "88.86.120.250" "88.86.120.213" "88.86.120.103" "46.234.104.23" "46.234.104.24")

echo -e "\n\n"

for ip in "${ips[@]}"
do
    echo -e "${GREEN}$ip${NOCOLOR}"
    spfquery -sender $email -ip $ip -helo kolbaba.stable.cz
    echo -e "\n\n"
done

Notice, there is RED commented out. That's because I would like the resulting message starting with any of these:

  • fail
  • softfail
  • neutral
  • unknown
  • error
  • none

i.e. not with:

  • pass

to colorize in red.

But how to do this is a mystery to me?

3 Answers3

24

With zsh instead of bash:

#! /bin/zsh -

email="info@vlastimilburian.cz"

ips=(88.86.120.{212,223,250,213,103} 46.234.104.{23,24})

print '\n\n'

for ip ($ips) { spfquery -sender $email -ip $ip -helo kolbaba.stable.cz && color=green || color=red

print -P "%F{$color}$ip%f\n" }

print -P turns on prompt expansion on the arguments where %F{color} is to set the foreground colour, and %f to reset it.

Note that the content of the variables in there ($color and $ip) are also subject to prompt expansion (something to bear in mind in cases where they may contain % characters (or more if the promptsubst option is enabled)), and without -r, escape sequence expansion (like \n above).

Other ways to access colours in zsh:

  • the colors autoloadable function:

    autoload colors; colors
    echo $fg[green]text$reset_color
    
  • the % parameter expansion flag, that enables prompt expansion on the content of a variable:

    var='%F{green}' reset=%f
    echo ${(%)var}text${(%)reset}
    

    see also:

    echo ${(%):-%F{green}}text${(%):-%f}
    

    or better

    printf '%s\n' "${(%):-%F{green}}$text${(%):-%f}"
    

    to guarantee the content of $text is output as-is.

  • the zsh/curses module used to write pseudo-graphical applications in the terminal.

9

You would want to check the exit code of spfquery, then have an if/else to see if it was a pass or not. Something like this:

#!/bin/bash

RED="\033[1;31m"
GREEN="\033[1;32m"
NOCOLOR="\033[0m"

email="info@vlastimilburian.cz"

declare -a ips=("88.86.120.212" "88.86.120.223" "88.86.120.250" "88.86.120.213" "88.86.120.103" "46.234.104.23" "46.234.104.24")

echo -e "\n\n"

for ip in "${ips[@]}"
do
    spfquery -sender $email -ip $ip -helo kolbaba.stable.cz

    exit_status=$?
    if [ $exit_status -eq 0 ]; then
        echo -e "${GREEN}$ip${NOCOLOR}"
    else
        echo -e "${RED}$ip${NOCOLOR}"
    fi

    echo -e "\n\n"
done
Jason Rush
  • 1,908
  • 1
  • 12
  • 12
  • I'm not sure. Per the documentation you linked for spfquery, a pass returns exit code 0, and each other return type returns a non-zero code (what we're checking for in the if statement). – Jason Rush Dec 05 '17 at 06:15
  • I will contact the developer and report it as a bug. Because it returns pass, while return code is 2. Thank you for the answer. – Vlastimil Burián Dec 05 '17 at 06:20
  • Explicitly comparing $? to zero is a widespread antipattern. Anything which looks like cmd; if [ $? -eq 0 ]; then is better written if cmd; then. The very purpose of the shell's flow control statements is to run a command sequence and check its exit status to decide a conditional. – tripleee Aug 15 '18 at 06:35
4

I would like the resulting message starting with any of these […] to colorize in red.

Your question reads that you would like to colour the output generated by the spfquery command. This is not achieved by running the command and then emitting colour change control sequences. What you are achieving with the other answers is colouring just the IP addresses. This may be what you want, but it is not what your question asks for.

The tools that you are looking for if this is what you really want to do are the various colourization filter utilities, such as István Karaszi's colorize, Radovan Garabík's grc, and Joakim Andersson's colortail. Configure them to recognize the appropriate things, and then pipe the output of spfquery, or indeed the entire for loop, through them.

Further reading

JdeBP
  • 68,745