Bash 中的逻辑运算在匹配模式时无法按预期工作

Logical operations in Bash do not work as expected when matching a pattern

你能告诉我这个脚本有什么问题吗?

if [[ " ${all[*]} " =~ " gcc " && \
      " ${all[*]} " =~ " release " && \
      false ]]
then
  additional_opts="gpu-compute-sanitizers"
else
  additional_opts=
fi

false 来自 GitHub 扩展,而 .yaml 文件中的实际脚本是:

if [[ " ${all[*]} " =~ " gcc " && \
      " ${all[*]} " =~ " release " && \
      ${{contains(github.event.pull_request.body, '[GPU Compute Sanitizers]')}} ]]
then
  additional_opts="gpu-compute-sanitizers"
else
  additional_opts=
fi

此脚本的问题是采用了第一个分支 (additional_opts="gpu-compute-sanitizers"),而拉取请求正文不包含关键字。

all 是一组选项,例如 gccrelease 或其他选项(clangdebug 等)。

OS 运行 GitHub 动作服务是 Ubuntu 18.04 .

问题在于,在 bash 条件表达式的上下文中,false 为真。或者更确切地说,bash 没有为字符串“false”赋予任何特殊含义,它只是像对待任何其他字符串一样对待。在条件表达式中,纯字符串被视为 -n(“此字符串是否为非空”)运算符的目标,并且由于“false”确实是非空的,因此结果为真。

来自bash documentation

-n string
string
True if the length of string is non-zero.

这是一个快速演示:

$ [[ true ]] && echo yes || echo no
yes
$ [[ false ]] && echo yes || echo no
yes
$ [[ wibble ]] && echo yes || echo no
yes
$ [[ "" ]] && echo yes || echo no
no

简单解决方案:测试结果是否为字符串“true”:

if [[ " ${all[*]} " =~ " gcc " && \
      " ${all[*]} " =~ " release " && \
      ${{contains(github.event.pull_request.body, '[GPU Compute Sanitizers]')}} = true ]]
then

(注意:我假设表达式的计算结果为“true”或“false”;如果它可能计算为其他值,您可能需要使用更复杂的测试。)