Issue
I have the following bash script:
#!/bin/bash
# login x times and calculate avg login time, take note of slowest time and # of logins > 1s
function login() {
startTime=$(date +%s)
curl --location --request GET 'http://www.example.com'
endTime=$(date +%s)
local callDuration=$(expr $endTime - $startTime)
echo "$callDuration"
}
numLogins=5
allCallDurations=()
echo "starting logins"
for i in $(seq $numLogins)
do
modu=$(expr $i % 20)
if [ $modu -eq "0" ]; then
echo "20 more calls were made"
fi
duration=$(login)
allCallDurations+=($duration)
done
avgDuration=$(expr $allCallDuration / $numLogins)
slowest=${allCallDurations[0]}
numSlowLogins=0
for i in $(seq $numLogins)
do
if (( slowest > ${allCallDurations[$i]} )); then
slowest=${allCallDurations[$i]}
fi
if (( ${allCallDurations[$i]} > 1 )); then
numSlowLogins=$(expr $numSlowLogins + 1)
fi
done
echo "finished:"
echo "average call duration (s): $avgDuration"
echo "slowest call (s): $slowest"
echo "# calls > 1 second: $numSlowLogins"
The idea is it uses curl
to make n
number of HTTP calls to a website (here I use example.com but in reality I'm making RESTful calls to my web service's login URL). It calculates the average call duration, the slowest call and the number of calls that took more than a second to return.
When I run this script through Shell Check it says everything is fine.
But when I run bash myscript.sh
(that's the name of this script on my Mac OS file system), I get:
bash myscript.sh
starting logins
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 772 100 704 100 68 3171 306 --:--:-- --:--:-- --:--:-- 3477
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 772 100 704 100 68 3142 303 --:--:-- --:--:-- --:--:-- 3446
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 772 100 704 100 68 3214 310 --:--:-- --:--:-- --:--:-- 3509
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 772 100 704 100 68 3142 303 --:--:-- --:--:-- --:--:-- 3446
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 772 100 704 100 68 3320 320 --:--:-- --:--:-- --:--:-- 3641
expr: syntax error
myscript.sh: line 45: {"json":"coming-back-from-server"}0")
myscript.sh: line 49: {"json":"coming-back-from-server"}0 > 1 ")
myscript.sh: line 45: {"json":"coming-back-from-server"}0")
myscript.sh: line 49: {"json":"coming-back-from-server"}1 > 1 : syntax error: operand expected (error token is "{"json":"coming-back-from-server"}1 > 1 ")
myscript.sh: line 45: {"json":"coming-back-from-server"}0")
myscript.sh: line 49: {"json":"coming-back-from-server"}0 > 1 ")
myscript.sh: line 45: {"json":"coming-back-from-server"}0")
myscript.sh: line 49: {"json":"coming-back-from-server"}0 > 1 ")
myscript.sh: line 45: {"json":"coming-back-from-server"}0")
myscript.sh: line 49: > 1 : syntax error: operand expected (error token is "> 1 ")
finished:
average call duration (s):
slowest call (s): {"json":"coming-back-from-server"}0
# calls > 1 second: 0
Where {"json":"coming-back-from-server"}
is just a placeholder for the actual json coming back from each curl execution, however its important to note that it is in fact printing JSON values for all of these.
Can anyone spot where I'm going awry, and why its failing whereas Shell Check says its good (I mean SC has a few warnings but no errors)?
Solution
As Charles Duffy has pointed out, shellcheck
cannot diagnose runtime errors/issues.
In this case the allCallDurations[]
array appears to be empty and this ties back to a typo in the program, consider the following spellings:
allCallDurations=() # array name ends in 's'
allCallDuration+=(duration) # missing 's' on end of array name
${allCallDurations[x]} # array name ends in 's'; multiple references
You're actually building a different array (allCallDuration
- no trailing s
) from what is referenced in the rest of the code (allCallDurations
- trailing s
).
So, fix the one typo and then see what happens:
# replace:
allCallDuration+=(duration)
# with:
allCallDurations+=(duration)
^-----
NOTE: I wouldn't expect shellcheck
to flag this issue since, technically, you are allowed to have 2 arrays with differeing names, even if the difference is a single trailing s
OK, so I can guess what the next couple issues may be ...
What's the difference in the following:
allCallDurations+=(duration) # previously suggested edit
allCallDurations+=($duration) # additional edit?
What do you think a call to login()
should be returning? What happens if you call login()
from the command prompt, ie, does it return what you're expecting?
Answered By - markp-fuso Answer Checked By - Willingham (WPSolving Volunteer)