Bash 为什么测试会显示意外的括号?
我的shell脚本中有一行Bash 为什么测试会显示意外的括号?,bash,shell,sh,Bash,Shell,Sh,我的shell脚本中有一行if,如下所示: if [ 0 -lt 2 -o (0 -gt 3 ) ] 这就产生了错误: line 3: syntax error near unexpected token `(' 因此,我查看了mantest,以确保parens得到了支持,并且可以肯定的是,它们非常接近手册页面的顶部!什么给你 上面的示例与代码不完全匹配,因为我试图清理它以证明一点,但这是在需要上下文的情况下进行的 编辑:更改了if行以匹配错误。您在[…]内有不必要的(…),它们未被替换和引
if
,如下所示:
if [ 0 -lt 2 -o (0 -gt 3 ) ]
这就产生了错误:
line 3: syntax error near unexpected token `('
因此,我查看了mantest
,以确保parens得到了支持,并且可以肯定的是,它们非常接近手册页面的顶部!什么给你
上面的示例与代码不完全匹配,因为我试图清理它以证明一点,但这是在需要上下文的情况下进行的
编辑:更改了if行以匹配错误。您在
[…]内有不必要的(…)
,它们未被替换和引用,导致语法错误
您可以改为使用此选项:
[[ $# -lt 2 || $# -gt 3 ]]
或使用:
[[ $# -lt 2 ]] || [[ $# -gt 3 ]]
括号作为参数传递给test
命令。[…]
表达式只是键入test
命令的另一种方式。唯一的区别是[
命令的最后一个参数必须是]
因此,应该像传递给命令的任何其他参数一样转义括号,以避免shell解释:
if[\($\-lt 2\)-o\($\-gt 3\)]
或者,使用单引号:
if['('$#-lt 2')'-o'('$#-gt 3')]
从信息页面:
‘测试’
`['
测试表达式
计算条件表达式表达式并返回状态0
(true)或1(false)。每个运算符和操作数必须是单独的
论点
顺便说一下,表达式可以重写如下:
如果内置测试\($#-lt 2\)-o \($#-gt 3\)
虽然这个解决方案没有直接回答这个问题,但是这里有一种使用C风格的替代方法,如果您在bash
#!/bin/bash
if (( "$#" < 2 || "$#" > 3 )); then
!/bin/bash
如果((“$#”<2 |“$#”>3)),那么
有趣的是,我认为这是因为引用,但我猜这个表达式$#-lt 2
总是会返回一些东西-要么0
要么1
,所以这不是引用问题。所以我认为你是对的。但还要注意,shell对待[
的方式与[
。除其他区别外,它允许使用未替换的括号。因此询问者实际上可以将他的[…]
更改为[…]]
,并保留他的括号。@anubhava:我不会说括号是不必要的,但显然是错误的。但有一点让我印象深刻:如果我以一种奇怪的方式使用paren,例如[(ls)]
,bash抱怨说意外的标记是ls,而不是括号。事实上,如果我重现这个示例,我会在意外的标记“$#”附近得到消息bash:syntax error。这让我怀疑OP是否真的使用了bash。很好的替代解决方案,但请注意子shell在这里不起作用:if(
和)
由shell解释,它们破坏了命令(并且从来没有创建过子shell)。如果(
和)
被正确引用,它们将由[
/测试
解释,它们是定义优先级的操作符(子shell的概念根本不起作用)。谢谢@mklement0,确实(…)
不会在[…]内创建任何子shell
这不能回答为什么测试会出现意外的括号?
问题。如果你想补充现有答案,请发表评论。@MarcinOrlowski:完全同意你的观点,我想强调一点,如果作者可以用这种比较方式,他一开始就不会出现这个错误。不是吗尽管这应该得到一个正确的答案。这并不能提供问题的答案。若要评论或要求作者澄清,请在其帖子下方留下评论。-@TobySpeight:我不确定我是否同意,请阅读我的上述评论MarcinOrlowski。这只是作者避免此类错误的另一种语法。全部:添加了cl正如@mklement0所建议的那样!+1可能有助于指出POSIX(~UNIX)规范将参数数量限制为4(搜索>4)in:也值得注意(来自同一链接页面):“指定-a
和-o
二进制原数和(
和)的XSI扩展名
运算符已被标记为已过时。(许多使用它们的表达式由语法根据要计算的特定表达式进行模糊定义。)”。建议使用单独的测试/[
语句,并将它们与&&
/|
组合。仅供参考,这是一个可以自动检测的错误。