我有以下bash脚本:
#!/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"
其想法是,它使用curl
对网站进行n
数量的HTTP调用(这里我使用example.com,但实际上我对web服务的登录URL进行RESTful调用(。它计算平均呼叫持续时间、最慢的呼叫以及需要一秒钟以上才能返回的呼叫数。
当我通过Shell Check运行这个脚本时,它会说一切都很好。
但当我运行bash myscript.sh
(这是我的Mac OS文件系统上这个脚本的名称(时,我得到:
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
其中{"json":"coming-back-from-server"}
只是每次curl执行后返回的实际json的占位符,但需要注意的是,它实际上正在打印所有这些的json值。
有人能发现我哪里出了问题吗?为什么它失败了,而Shell Check说它很好(我的意思是SC有一些警告,但没有错误(?
shellcheck
无法诊断运行时错误/问题。
在这种情况下,allCallDurations[]
数组似乎是空的,这与程序中的拼写错误有关,请考虑以下拼写:
allCallDurations=() # array name ends in 's'
allCallDuration+=(duration) # missing 's' on end of array name
${allCallDurations[x]} # array name ends in 's'; multiple references
实际上,您正在构建一个与代码其余部分(allCallDurations
-尾随s
(中引用的不同的数组(allCallDuration
-没有尾随s
(。
所以,修复一个拼写错误,然后看看会发生什么:
# replace:
allCallDuration+=(duration)
# with:
allCallDurations+=(duration)
^-----
注意:我不希望shellcheck
标记此问题,因为从技术上讲,允许有两个具有不同名称的阵列,即使差异是单个尾随的s
好吧,所以我可以猜测接下来的几个问题可能是什么。。。
以下内容有什么区别:
allCallDurations+=(duration) # previously suggested edit
allCallDurations+=($duration) # additional edit?
你认为login()
的电话应该回什么?如果您在命令提示符下调用login()
,会发生什么,即它是否返回您所期望的内容?
在中
if (( slowest > ${allCallDurations[$i]} )); then
除非我们在运行时知道${allCallDurations[$i]}
扩展为" "
而不是数字,否则没有什么是无效语法。静态检查无法检测到。
除此之外:expr
不应在现代代码中使用。使用$(( ))
进行整数运算,或使用bc
进行浮点运算。