【问题标题】:if fi [: too many argumentsif fi [: 参数太多
【发布时间】:2013-10-26 15:59:52
【问题描述】:

这个脚本有问题吗?

if [ grep -q "#<filter>" /etc/hosts ] &&  [ grep -q "#</filter>" /etc/hosts ] ; then
 echo "exist"
fi

它显示的错误是:

[: too many arguments

【问题讨论】:

    标签: bash if-statement arguments


    【解决方案1】:

    问题是您将普通命令包装在[ 语法中。这是无效的。 [ 标记实际上是一个命令,它将其参数解释为一种非常有限的表达式语言,用于进行字符串和数字比较,以及文件和目录的条件,例如与类型、存在、时间戳有关的测试。

    在 shell 语法中,您可以将一系列命令包装在 (...) 括号中。这样做的效果是在新的子进程中运行封闭的命令。您还可以使用大括号对命令进行分组以创建组命令。

    &amp;&amp; 和 || 命令具有相同的优先级;它不像 C 语言中的类似排序。基本上,如果您有一个命令,您可以使用|| another command 或&amp;&amp; another command 附加另一个命令。 || 运算符表示:如果此处左侧的所有内容都失败,请运行以下命令。 “这样做,否则如果失败,就这样做”。 &amp;&amp; 操作符的意思是:如果到目前为止一切都成功了,还请执行以下操作。

    如果您想要(A || B) &amp;&amp; (C || D) 之类的逻辑——换句话说,A、B、C 和 D 必须按该顺序运行,并且您希望每个 || 组中至少有一个命令成功,那可以是用这样的大括号完成:

    { A || B; } && { C || D; }
    

    如果您不介意为了控制评估而分叉子进程,或者使用括号。请注意,组命令语法中需要分号;否则必须使用换行符,并且大括号周围必须有空格。

    没有大括号,A || B &amp;&amp; C || D 与A || { B &amp;&amp; { C || D; } } 的含义相同:它本质上是具有同等优先级的右结合。而且,顺便说一下,&amp; 运算符(后台作业)的优先级较低,A || B &amp;&amp; C || D &amp; 意味着将整个该死的东西放在后台,而不仅仅是 D。

    【讨论】:

      【解决方案2】:

      尝试使用更好的boolean approach

      if grep -q "#<filter>" /etc/hosts &&  grep -q "#</filter>" /etc/hosts; then
       echo "exist"
      fi
      

      那里不需要测试命令([ ])

      [ ] 期望一个带有开关的表达式,例如 [ -s file ] 或单个变量,例如 [ $SHELL ],但不是像您尝试的完整命令行。

      【讨论】:

      • 澄清一下:问题是[ ... ] 看起来像语法,但实际上是test 命令的另一个名称。 if 语句的条件不需要括号。
      【解决方案3】:

      您只需要使用 lookahead regex 的 1 个条件,如下所示:

       grep -qP "#<filter>(?=[\s\S]*#</filter>)" && echo "exists"
      

      【讨论】:

      • 这里不是 AND 而是 OR 布尔逻辑。这意味着不检查两个字符串,而只检查一个字符串的存在
      • @sputnick: &amp;&amp; 表示 grep 成功。
      • 我知道,我的意思不是这部分,而是你的正则表达式。这不是 OP 要求的。
      • 我认为 sputnick 的意思是它不是 OR 而是 AND 逻辑,对吧?
      猜你喜欢
      • 2013-04-18
      • 2015-05-11
      • 1970-01-01
      • 2020-12-03
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多