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

1wnzp6jl  于 2022-11-16  发布在  Shell
关注(0)|答案(2)|浏览(198)

我有以下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执行返回的 actual json的占位符,但需要注意的是,它实际上是为所有这些内容打印JSON值。
有人能发现我哪里出错了吗,为什么它失败了,而Shell Check说它很好(我的意思是SC有一些 * 警告 *,但没有错误)?

yebdmbv4

yebdmbv41#

正如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

实际上,您构建的数组(allCallDuration-没有尾随的s)与其余代码中引用的数组(allCallDurations-尾随的s)不同。
因此,修复一个错别字,然后看看会发生什么:

# replace:

allCallDuration+=(duration) 

# with:

allCallDurations+=(duration)    
               ^-----

**注意:**我不希望shellcheck标记此问题,因为从技术上讲,允许有两个名称不同的数组,即使差异是一个尾随的s

好的,我可以猜到接下来的几个问题是什么...
以下有何不同:

allCallDurations+=(duration)          # previously suggested edit

allCallDurations+=($duration)         # additional edit?

你认为调用login()应该返回什么?如果你从命令提示符下调用login()会发生什么,也就是说,它会返回你所期望的吗?

q35jwt9p

q35jwt9p2#

if (( slowest > ${allCallDurations[$i]} )); then

......除非我们在运行时知道${allCallDurations[$i]}扩展为" "而不是数字,否则没有什么是无效语法。静态检查无法检测到它。
除此之外:不应在现代代码中使用expr。请将$(( ))用于整数运算,或将bc用于浮点运算。

相关问题