我在批处理脚本中有以下两行
iperf_options=" -O 10 -V -i 10 --get-server-output -P " $streams
$iperf_options=$iperf_options $proto
和
$streams = 2
$proto = -u
但是当我运行这个时,我得到以下错误:
。/bandwidth: line 116: -O: command not found
我只是想写一个字符串,然后把它附加到一个变量,所以为什么它抛出错误上-O?
我已经在网上找过了,但是我似乎只是找到了一些关于"=">
非常感谢您的帮助。
谢谢
代码块显示错误
proto=-u
streams=2
iperf_options=" -O 10 -V -i 10 --get-server-output -P " $streams
$iperf_options=$iperf_options $proto
运行this将输出
./test
./test: line 3: 2: command not found
./test: line 4: =: command not found
这里有两个主要的错误,在各种组合中。
-
使用
$
获取变量的值,不要在设置变量(或更改其属性)时使用:$var=value # Bad var=value # Good var=$othervar # Also good
-
空格是shell语法中的关键分隔符;添加(或删除)它们可以以意想不到的方式改变命令的含义:
var = value # Runs `var` as a command, passing "=" and "value" as arguments var=val1 val2 # Runs `val2` as a command, with var=val1 set in its environment var="val1 val2" # Sets `var1` to `val1 val2`
那么,在这个命令中:
iperf_options=" -O 10 -V -i 10 --get-server-output -P " $streams
iperf_options="..."
和$streams
之间的空格意味着它将扩展$streams
并尝试将其作为命令运行(在其环境中设置iperf_options
)。你想要这样的:iperf_options=" -O 10 -V -i 10 --get-server-output -P $streams"
这里,由于
$streams
是双引号字符串的一部分,它将被展开(变量在双引号内展开,而不是在单引号内展开),并且它的值包含在分配给iperf_options
的值中。
实际上还有第三个错误(或者至少是可疑的脚本实践):将选项列表构建为简单的字符串变量。这在简单的情况下有效,但在事情变得复杂时就失效了。如果你正在使用支持数组的shell(例如bash, ksh, zsh等,但不支持dash),最好使用这些,并将每个选项/参数存储为单独的数组元素,然后使用"${arrayname[@]}"
扩展数组以完整地获取所有元素(是的,所有这些引号,大括号,括号等实际上都是需要的)。
proto="-u" # If this'll always have exactly one value, plain string is ok
streams=2 # Same here
iperf_options=(-O 10 -V -i 10 --get-server-output -P "$streams")
iperf_options=("${iperf_options[@]}" "$proto")
# ...
iperf "${iperf_options[@]}"
最后,我推荐shellcheck.net对您的脚本进行安全检查,以查找常见错误。一个警告:它不会捕获所有的错误,因为它不知道你的意图。例如,如果它看到var=val1 val2
,它会认为你的意思是要将val2
作为命令运行,而不会将其标记为错误。