0

这个脚本有问题吗?

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

它显示的错误是:

[: too many arguments
4

3 回答 3

6

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

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

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

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

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

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

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

于 2013-10-26T16:22:12.410 回答
3

尝试使用更好的布尔方法

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

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

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

于 2013-10-26T16:02:15.397 回答
1

您只需要使用lookahead regex这样的 1 个条件:

 grep -qP "#<filter>(?=[\s\S]*#</filter>)" && echo "exists"
于 2013-10-26T16:05:23.717 回答