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 filenameif [ -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”运算符的主要内容,如果未能解决你的问题,请参考以下文章

PHP 运算符 if 语句 'and' 和 'or'

linux基础--Bash逻辑控制语句

Bash 中的简单逻辑运算符

在 if 语句中使用 && 运算符

bash脚本中 if 语句 和 for 语句的用法

17.自学Linux之路:bash编程之条件判断语句