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

Time:11-04

Could you please tell me what's wrong with this script?

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

false comes from GitHub extensions while the actual script in the .yaml file is:

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

The problem with this script is that the first branch is taken (additional_opts="gpu-compute-sanitizers"), while the pull request body doesn't contain the keyword.

all is an array of options like gcc and release or something else (clang, debug, etc).

The OS running the GitHub actions service is Ubuntu 18.04 .

CodePudding user response:

The problem is that, in the context of a bash conditional expression, false is true. Or rather, bash doesn't assign any special meaning to the string "false", it's just treated like any other string. In a conditional expression, a plain string is treated as though it had was the target of a -n ("is this string nonblank") operator, and since "false" is indeed nonblank the result comes out as true.

From the bash documentation:

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

Here's a quick demo:

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

Simple solution: test to see whether the result is the string "true":

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

(Note: I'm assuming that expression will evaluate to either "true" or "false"; if it might evaluate to something else, you may have to use a more complicated test.)

  • Related