这个脚本有问题吗?
if [ grep -q "#<filter>" /etc/hosts ] && [ grep -q "#</filter>" /etc/hosts ] ; then
echo "exist"
fi
它显示的错误是:
[: too many arguments
答案 0 :(得分:6)
问题是您使用[
语法包装普通命令。这是无效的。 [
标记实际上是一个命令,它将其参数解释为用于进行字符串和数字比较的非常有限的表达式语言,以及文件和目录的条件,例如与类型,存在,时间戳有关的测试。 / p>
在shell语法中,您可以在(...)
括号中包装一系列命令。这样做的结果是在新的子进程中运行所附的命令。您还可以使用大括号对命令进行分组以创建组命令。
&&
和||
命令具有相同的优先级;它不像C语言中的类似排序。基本上,如果您有命令,则可以使用|| another command
或&& 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
。
答案 1 :(得分:3)
使用更好的boolean approach
尝试此操作if grep -q "#<filter>" /etc/hosts && grep -q "#</filter>" /etc/hosts; then
echo "exist"
fi
不需要测试命令([ ]
)
[ ]
期望带有开关的表达式(如[ -s file ]
)或单个变量(如[ $SHELL ]
),但不会像您尝试的那样使用完整的命令行。
答案 2 :(得分:1)
使用lookahead regex
只需要1个条件:
grep -qP "#<filter>(?=[\s\S]*#</filter>)" && echo "exists"