J V
J V

Reputation: 11936

Bash escaping and syntax

I have a small bash file which I intend to use to determine my current ping vs my average ping.

#!/bin/bash
output=($(ping -qc 1 google.com | tail -n 1))
echo "`cut -d/ -f1 <<< "${output[3]}"`-20" | bc

This outputs my ping - 20 ms, which is the number I want. However, I also want to prepend a + if the number is positive and append "ms".

This brings me to my overarching problem: Bash syntax regarding escaping and such heavy "indenting" is kind of flaky.

While I'll be satisfied with an answer of how to do what I wanted, I'd like a link to, or explanation of how exactly bash syntax works dealing with this sort of thing.

Upvotes: 0

Views: 174

Answers (4)

user000001
user000001

Reputation: 33317

Bash cannot handle floating point numbers. A workaround is to use awk like this:

#!/bin/bash
output=($(ping -qc 1 google.com | tail -n 1))
echo "`cut -d/ -f1 <<< "${output[3]}"`-20" | bc | awk '{if ($1 >= 0) printf "+%fms\n", $1; else printf "%fms\n", $1}'

Note that this does not print anything if the result of bc is not positive

Output:

$ ./testping.sh 
+18.209000ms

Upvotes: 0

William
William

Reputation: 4925

Here's my take on it, recognizing that the result from bc can be treated as a string:

output=($(ping -qc 1 google.com | tail -n 1))
output=$(echo "`cut -d/ -f1 <<< "${output[3]}"`-20" | bc)' ms'
[[ "$output" != -* ]] && output="+$output"
echo "$output"

Upvotes: 0

Barmar
Barmar

Reputation: 780724

output=($(ping -qc 1 google.com | tail -n 1))
echo "${output[3]}" | awk -F/ '{printf "%+fms\n", $1-20}'

The + modifier in printf tells it to print the sign, whether it's positive or negative.

And since we're using awk, there's no need to use cut or bc to get a field or do arithmetic.

Upvotes: 1

that other guy
that other guy

Reputation: 123410

Escaping is pretty awful in bash if you use the deprecated `..` style command expansion. In this case, you have to escape any backticks, which means you also have to escape any other escapes. $(..) nests a lot better, since it doesn't add another layer of escaping.

In any case, I'd just do it directly:

ping -qc 1 google.com.org | awk -F'[=/ ]+' '{n=$6} 
    END { v=(n-20); if(v>0) printf("+"); print v}'

Upvotes: 0

Related Questions