1

I am trying to compare if traceroute got successful or not in a bash. This is what I execute.

traceroute -m 30 -n 8.8.8.8 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'

Output I receive:

8.8.8.8

8.8.8.8

192.192.192.21

192.191.191.32

192.18.128.48

8.8.8.8

192.168.168.168

I want to compare 8.8.8.8 (first value of the array) with last 3 values of the array, but when I try it, I get the error for float comparison.

Edit:

I tried this code, but it gives me error for float comparison.

for i in ${my_array[@]};
do
        if [ "${my_array[0]}" == "${my_array[i+1]}" ]; then
                echo "values are same";
        else
                echo "values are not same";
        fi
        echo $i;    
done

I know it is possible to use "bc" to solve float comparison problem, but is there any other way to solve this inline rather than storing it in an array ?

tech_enthusiast
  • 683
  • 3
  • 12
  • 37
  • How are you comparing it? What is your expected output? – anubhava Jun 28 '18 at 10:11
  • @anubhava , My expectation is that - if a first or second value (8.8.8.8) matches with remaining values , then i should get "1". I want to verify if route is reachable or not with "traceroute". – tech_enthusiast Jun 28 '18 at 10:15

2 Answers2

2

I want to compare 8.8.8.8 (first value of the array) with last 3 values of the array

Just get the first value in the output and grep it with the last 3 lines:

output="8.8.8.8

8.8.8.8

192.192.192.21

192.191.191.32

192.18.128.48

8.8.8.8

192.168.168.168"

output=$(sed '/^$/d' <<<"$output") # remove empty lines

if grep -q "$(head -n1 <<<"$output")" <(tail -n3 <<<"$output"); then
        echo "Last three lines of output contain first line of the output"
else
        echo "fus ro dah"
fi

Now to your code:

for i in ${my_array[@]};

Iterates over values in my_array. If you want indexes of an array you need to iterate over them with for ((i = 0; i < ${#my_array[@]}; ++i)). Now I guess this:

for ((i = ${#my_array[@]} - 3; i < ${#my_array[@]}; ++i)); do
        if [ "${my_array[0]}" = "${my_array[i]}" ]; then
                echo "values are same";
        else
                echo "values are not same";
        fi
        echo $i;    
done

will probably do what you want, but using grep:

if grep -q "${my_array[0]}" <(printf "%s\n" "${my_array[@]: -3}"); then
    echo "values are same"
else
    echo "values are not same"
fi

is still simpler (for me).
Also note that the string comparison "operator" (dunno how it's called) in test is = not ==.

KamilCuk
  • 120,984
  • 8
  • 59
  • 111
2

You may use this awk for your requirement:

traceroute -m 30 -n 8.8.8.8 |&
awk '$1=="traceroute"{ip=$3} /ms$/{a[++n] = ($1+0 == $1 ? $2 : $1)}
     END{for (i=n-2; i<=n; i++) if (ip == a[i]) exit 1}'

It will exit with status 1 when any IP address in last 3 lines match with IP in first line that starts with traceroute. If there is no match then exit status will be 0.

anubhava
  • 761,203
  • 64
  • 569
  • 643