Bash 中“if”语句的“and”运算符
Posted
技术标签:
【中文标题】Bash 中“if”语句的“and”运算符【英文标题】:An "and" operator for an "if" statement in Bash 【发布时间】:2012-11-04 16:48:42 【问题描述】:我正在尝试创建一个简单的 Bash 脚本来检查网站是否已关闭,并且由于某种原因“and”运算符不起作用:
#!/usr/bin/env bash
WEBSITE=domain.com
SUBJECT="$WEBSITE DOWN!"
EMAILID="an@email.com"
STATUS=$(curl -sI $WEBSITE | awk '/HTTP\/1.1/ print $2 ')
STRING=$(curl -s $WEBSITE | grep -o "string_to_search")
VALUE="string_to_search"
if [ $STATUS -ne 200 ] && [[ "$STRING" != "$VALUE" ]]; then
echo "Website: $WEBSITE is down, status code: '$STATUS' - $(date)" | mail -s "$SUBJECT" $EMAILID
fi
“-a”运算符也不起作用:
if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
能否请您告知何时使用:
单方括号和双方括号 括号?
【问题讨论】:
您能否更准确地说明什么“不起作用”?您是否有特定的错误消息,或者根本没有提供预期的输出? 我实际上收到了“预期的一元运算符”,所以看起来引用有帮助-a
具有重复性。当与 Bourne shell 风格的 test
命令(又名 [
)一起使用时,它的意思是 and
。当用作 条件表达式 时,它正在测试文件是否存在。是的,这令人困惑,最好避免。
看看这个:theunixshell.blogspot.com/2013/05/…
【参考方案1】:
试试这个:
if [ "$STATUS" -ne 100 -a "$STRING" = "$VALUE" ]
或
if [ "$STATUS" -ne 100 ] && [ "$STRING" = "$VALUE" ]
【讨论】:
加上最干净的例子【参考方案2】:引用:
“-a”运算符也不起作用:
如果 [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
更详细的解释:[
和 ]
不是 Bash 保留字。 if
关键字引入了要由作业评估的条件(如果作业的返回值为 0
,则条件为真,否则为假)。
对于简单的测试,有test
程序 (man test
)。
由于某些行如if test -f filename; then foo bar; fi
等令人讨厌,在大多数系统上,您会发现一个名为[
的程序实际上只是test
程序的符号链接。当test
被称为[
时,您必须添加]
作为最后一个位置参数。
所以if test -f filename
与if [ -f filename ]
基本相同(就产生的进程而言)。在这两种情况下,test
程序都会启动,并且两个进程的行为应该相同。
这是你的错误:if [ $STATUS -ne 200 ] -a [[ "$STRING" != "$VALUE" ]]
将解析为 if
+ 一些工作,工作是除了 if
本身之外的所有内容。这项工作只是一个简单的命令(Bash 表示会导致单个进程的东西),这意味着第一个单词 ([
) 是命令,其余的是它的位置参数。 在第一个]
之后还有剩余的参数。
同样不是,[[
确实是一个 Bash 关键字,但在这种情况下它只被解析为一个普通的命令参数,因为它不在命令的前面。
【讨论】:
【参考方案3】:除非$STATUS
为空,否则您所拥有的应该可以工作。这样做可能会更好:
if ! [ "$STATUS" -eq 200 ] 2> /dev/null && [ "$STRING" != "$VALUE" ]; then
或
if [ "$STATUS" != 200 ] && [ "$STRING" != "$VALUE" ]; then
很难说,因为你没有向我们确切地展示你的脚本出了什么问题。
个人意见:永远不要使用[[
。它抑制重要的错误消息,并且不能移植到不同的 shell。
【讨论】:
如果STATUS
为空,来自@HTF 的代码将在-ne: unary operator expected
上失败。在你的情况下,它会在integer expression expected
上失败,不是吗?
我明白这一点。但是您强调了$STATUS
可能为空的问题并提出了解决方案(引用它)。你的解决方案仍然失败,STATUS
是空的,这就是我的意思。
@jvivenot 你说得有道理。 (我对您的评论的回复是在您编辑评论之前做出的,当时您的评论只是“代码......会失败”。一个简单的解决方案是使用$STATUS:-0"
。将编辑。
进一步,考虑由 [[ 在a="this is not an integer"; test "$a" -ge 0; [[ $a -ge 0 ]];
IMO 中生成的(缺少)错误消息,该错误消息很有用,并且 [[ 错误地抑制了它。此外,[[ 返回 0,而 test 返回 1。IMO,这使得 [[
无法使用。
@Mercury 是的,我对此持强烈的看法。缺少来自[[
的错误消息是有问题的。 [[
解决了因对test
工作原理的误解而引起的问题。 IMO,解决这些问题的更好方法是了解如何使用test
。【参考方案4】:
试试这个:
if [ $STATUS -ne 200 -a "$STRING" != "$VALUE" ]; then
【讨论】:
为我工作。我认为可能有不止一种方法,但我现在对此感到满意。 看起来在某些情况下效果更好。 && 运算符看起来不适用于 shell 替换和两个 &&。我建议先试试这个选项。以上是关于Bash 中“if”语句的“and”运算符的主要内容,如果未能解决你的问题,请参考以下文章