Bash Shell检查通过脚本,但在运行时出现语法错误:应为操作数



我有以下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有一些警告,但没有错误(?

正如Charles Duffy所指出的,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进行浮点运算。

最新更新