0

I've downloaded a script from github, which seems to work, but I'm getting the error when running.

https://github.com/chentda/curl-average-timings

The script calculates the average loading time from a URL

#!/bin/bash

#This is a simple bash script to get the averages of various website response timings using cURL

#Formatted cURL output that contains the various response timings separated by '-'
curl_format="%{time_namelookup}-%{time_connect}-%{time_appconnect}-%{time_pretransfer}-%{time_redirect}-%{time_starttransfer}-%{time_total}"
#Website you want to send the request to
URL="https://www.google.com/"
#How many requests you want to hit website with to get averages
iterations=5
decimal_rounding=5

#Initialising total variables for the various timings
total_time_namelookup="0"
total_time_connect="0"
total_time_appconnect="0"
total_time_pretransfer="0"
total_time_redirect="0"
total_time_starttransfer="0"
total_time_total="0"

for i in `seq 1 $iterations`;
do
    response=$(curl -o /dev/null -s -w $curl_format $URL)

    #Splits response string by the delimiter of "-"
    response_times=($(echo "$response" | tr "-" "\n"))

    #Assigning each type of response time to a variable
    time_namelookup=${response_times[0]}
    time_connect=${response_times[1]}
    time_appconnect=${response_times[2]}
    time_pretransfer=${response_times[3]}
    time_redirect=${response_times[4]}
    time_starttransfer=${response_times[5]}
    time_total=${response_times[6]}

    #Adding variables assigned above in loop to the respective total variables that are set at start of script
    total_time_namelookup=$(echo "$total_time_namelookup + $time_namelookup" | bc)
    total_time_connect=$(echo "$total_time_connect + $time_connect" | bc)
    total_time_appconnect=$(echo "$total_time_appconnect + $time_appconnect" | bc)
    total_time_pretransfer=$(echo "$total_time_pretransfer + $time_pretransfer" | bc)
    total_time_redirect=$(echo "$total_time_redirect + $time_redirect" | bc)
    total_time_starttransfer=$(echo "$total_time_starttransfer + $time_starttransfer" | bc)
    total_time_total=$(echo "$total_time_total + $time_total" | bc)
done

#Calculating the average for each type of response time
average_time_namelookup=$(echo "scale=$decimal_rounding; $total_time_namelookup / $iterations" | bc)
average_time_connect=$(echo "scale=$decimal_rounding; $total_time_connect / $iterations" | bc)
average_time_appconnect=$(echo "scale=$decimal_rounding; $total_time_appconnect / $iterations" | bc)
average_time_pretransfer=$(echo "scale=$decimal_rounding; $total_time_pretransfer / $iterations" | bc)
average_time_redirect=$(echo "scale=$decimal_rounding; $total_time_redirect / $iterations" | bc)
average_time_starttransfer=$(echo "scale=$decimal_rounding; $total_time_starttransfer / $iterations" | bc)
average_time_total=$(echo "scale=$decimal_rounding; $total_time_total / $iterations" | bc)

echo "Averages of response timings:"
echo ""
echo "   time_namelookup: $average_time_namelookup"
echo "      time_connect: $average_time_connect"
echo "   time_appconnect: $average_time_appconnect"
echo "  time_pretransfer: $average_time_pretransfer"
echo "     time_redirect: $average_time_redirect"
echo "time_starttransfer: $average_time_starttransfer"
echo "                    --------"
echo "        time_total: $average_time_total"

After a few debuggin, I can see that the problem is on this line, when uses bc to sum results

total_time_namelookup=$(echo "$total_time_namelookup + $time_namelookup" | bc)

But it throws

(standard_in) 1: syntax error 

But I can't figure what I'm doing wrong.

I'm on ubuntu running from the terminal with sh

dragonalvaro
  • 703
  • 1
  • 10
  • 28
  • If that's the line, one of the variables probably doesn't contain a numeric value. Print them out to confirm. You could also do `((total_time_namelookup = total_time_namelookup + time_namelookup))` to let [tag:bash] itself do the addition and to avoid spawning a `bc` process. – Ted Lyngmo Oct 02 '20 at 12:17
  • I've printed the variables, but they seems to be ok. They are decimals but nothing strange... I testes the line with numerics values set by hand for me and seems to work. – dragonalvaro Oct 02 '20 at 12:24
  • So, what's the problem with that line? You print both values before you do the calculation and they look ok, but the result in `total_time_namelookup` is wrong? – Ted Lyngmo Oct 02 '20 at 12:25
  • yes, it throws (standard_in) 1: syntax error – dragonalvaro Oct 02 '20 at 12:31
  • If you add this line before the line you suspect, what does it show: `echo -e ">$total_time_namelookup<\n>$time_namelookup<"` ? – Ted Lyngmo Oct 02 '20 at 12:36
  • Does your script or its data have DOS line endings? See https://stackoverflow.com/questions/39527571/are-shell-scripts-sensitive-to-encoding-and-line-endings – tripleee Oct 02 '20 at 12:41
  • 1
    That's a horrible mess of `bc` pipes, though; looks like the script wants to be rewritten in Awk. – tripleee Oct 02 '20 at 12:43
  • @TedLyngmo >0< >0,012221 – dragonalvaro Oct 02 '20 at 12:44
  • @tripleee :) Yeah. but it's probably doable if one adds some validation. – Ted Lyngmo Oct 02 '20 at 12:44
  • 2
    @dragonalvaro Aha! There's a comma in the decimal value. Does your `bc` run in the same `locale` as the program that returned that value? `echo 0 + 0,012221 | bc` gives me `(standard_in) 1: syntax error` too. Looking at `bc` I'm not sure you can affect its `locale`. Just `tr ',' '.'` on the strings. – Ted Lyngmo Oct 02 '20 at 12:45
  • `bc` only work with `LC_NUMERIC=C` or `LC_NUMERIC=POSIX` formatted floats. Even `awk` will fail if numbers are not formatted to these locales. – Léa Gris Oct 02 '20 at 12:51
  • Or maybe add `export LC_ALL=C` near the top of the script. – tripleee Oct 02 '20 at 12:53
  • @tripleee Yeah, if it doesn't come from an external source. I added that as an option. – Ted Lyngmo Oct 02 '20 at 12:53

1 Answers1

4

Your numeric values contains a locale specific decimal separator (,). bc only knows .. Convert your string containing numeric values by running them through tr , '.' before sending them to bc.

Or, as suggested by tripleee, set the C locale explicitly at the top of the script:

export LC_ALL=C

For more complex locale operations, you may need library support: https://github.com/leagris/lcnumconv.sh

Ted Lyngmo
  • 93,841
  • 5
  • 60
  • 108
  • 1
    locale numeric formats conversion are more complex than switching comma separator, switching thousands separators and neither awk or bash have proper tools to do so. This is why I wrote a featured Bash library to do it: https://github.com/leagris/lcnumconv.sh – Léa Gris Oct 02 '20 at 12:56
  • Looks nice. I added a link to that bash library. – Ted Lyngmo Oct 02 '20 at 12:58
  • 2
    thank you. I was strugglin to use the tr command (I'm a bash noob) but that worked like a charm. Thank you very much – dragonalvaro Oct 02 '20 at 13:34