【发布时间】: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
这个脚本有问题吗?
if [ grep -q "#<filter>" /etc/hosts ] && [ grep -q "#</filter>" /etc/hosts ] ; then
echo "exist"
fi
它显示的错误是:
[: too many arguments
【问题讨论】:
标签: bash if-statement arguments
问题是您将普通命令包装在[ 语法中。这是无效的。 [ 标记实际上是一个命令,它将其参数解释为一种非常有限的表达式语言,用于进行字符串和数字比较,以及文件和目录的条件,例如与类型、存在、时间戳有关的测试。
在 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。
【讨论】:
尝试使用更好的boolean approach
if grep -q "#<filter>" /etc/hosts && grep -q "#</filter>" /etc/hosts; then
echo "exist"
fi
那里不需要测试命令([ ])
[ ] 期望一个带有开关的表达式,例如 [ -s file ] 或单个变量,例如 [ $SHELL ],但不是像您尝试的完整命令行。
【讨论】:
[ ... ] 看起来像语法,但实际上是test 命令的另一个名称。 if 语句的条件不需要括号。
您只需要使用 lookahead regex 的 1 个条件,如下所示:
grep -qP "#<filter>(?=[\s\S]*#</filter>)" && echo "exists"
【讨论】:
&& 表示 grep 成功。