我在这行代码中的Bash shell脚本 script.sh 中出错:
{
"action":"add",
"domain":"dm1",
"params":{
"add1":"v1",
"add2":"v2",
"add3":"v3"
}
}
错误是:let initialLines=$(grep '' "$1" | wc -l || true)
这里的语法错误是什么?
答案 0 :(得分:4)
<强> TL;博士强>:
双引号命令替换:
let initialLines="$(grep '' "$1" | wc -l || true)"
那就像chepner's helpful answer中所解释的那样,你可以使用一个简单的赋值而不需要引用RHS,虽然为了得到与let
相同的结果,一定要声明首先是-i
的变量;例如,declare -i initialLines
看起来像你的任务的 RHS - 命令替换($(...)
) - 评估空字符串或空白前缀shell expansions过程中的> string ,以便bash
最终尝试解析以下命令之一:
let initialLines=
let initialLines= 2
如果您单独试用这些内容,则会收到您遇到过的语法错误。
最可能的解释是您正在使用 BSD wc
,例如在macOS上,它会使用输出-l
所请求的行数领先的空白。
简单修复是双引号命令替换:
let initialLines="$(grep '' "$1" | wc -l || true)"
至于命令替换中的命令(它可能只是一个例子,但它值得评论):
grep ''
将始终返回所有输入行,因此它只不过是效率较低的cat
。
使用|| true
:
即使set -e
生效,运行命令替换的子shell的退出代码也无关紧要。
此外,通过使用true
作为替代命令,您也可以中断let
命令,因为内置true
没有标准输出
总之,您的整个命令替换可以缩减为wc -l < "$1"
。
答案 1 :(得分:2)
此处几乎不需要使用let
命令。
initialLines=$(grep '' "$1" | wc -l)
这解决了@ mklement0以不同方式指出的问题(产生空白或空白前缀字符串的命令替换);与let
命令的参数不同,赋值右侧的值不受字拆分的影响。