为什么我的 if 语句向后解释布尔值

为什么我的 if 语句向后解释布尔值

我对 .zshrc 中几个函数的输出感到非常困惑。

function __isred {
  if [[ $(ps cax | grep redshift | wc -l) > 0 ]]
  then
    return 1
  else
    return 0
  fi
}

function __togred {
  if __isred
  then
    killall redshift
  else
    redshift &
  fi
} 

__isred 的想法是,如果 redshift 正在运行,它将返回 true,否则返回 false。我可以确认它使用 echo 返回正确的输出。但是,当输出为 1 时,__togred 中的 if 语句将转到 else 块而不是 then。我在这里缺少什么吗?

答案1

对于 shell 命令,0 退出状态表示 true/成功,其他任何值表示 false/失败(使用确切的值来区分不同类型的失败)。最好是首先避免使用精确的退出状态值,而使用falsetrue命令代替:

__isred() {
  if [[ $(ps cax | grep redshift | wc -l) > 0 ]]
  then
    true
  else
    false
  fi
}

此时,您开始意识到这有点愚蠢,因为您可以这样做:

__isred() [[ $(ps cax | grep redshift | wc -l) > 0 ]]

请注意,这[[ > ]]是为了词法比较。在这里使用数字比较会更有意义:

__isred() (( $(ps cax | grep redshift | wc -l) > 0 ))

但实际上,如果您只想检查是否至少出现过一次,则无需计算出现的次数:

__isred() { ps cax | grep -q redshift; }

应该够了。grep如果正则表达式匹配,将返回成功。

现在,当您使用非标准ps语法时,您可能希望使用稍微更便携的pgrep命令来 更轻松、更可靠地执行ps此操作:grep

__isred() { pgrep redshift > /dev/null; }

答案2

来自zsh手册:

if list then list [ elif list then list ] ... [ else list ] fi    
    The if list is executed, and if it returns a zero exit status, the then list is executed.
    Otherwise, the elif list is executed and if its status is zero, the then list is executed.
    If each elif list returns nonzero status, the else list is executed.

在unix系统上,按照惯例,返回值0表示成功。这是违反直觉的,但却是有道理的,因为这允许命令针对不同的错误使用不同的返回值。

相关内容