2

I have a scenario where I am running the following code:

error_count=0
(cd tmp1 && terraform init -backend=false > /dev/null && terraform validate && echo "Terraform format check passed successfully in -------> xxx" && rm -rf .terraform*) || (echo "Terraform validation failed in xxx" && cd tmp && rm -rf .terraform* && let "error_count=error_count+1")

(cd tmp2 && terraform init -backend=false > /dev/null && terraform validate && echo "Terraform format check passed successfully in -------> yyy" && rm -rf .terraform) || (echo "Terraform validation failed in yyy" && cd tmp && rm -rf .terraform && let "error_count=error_count+1") echo $error_count if [ "$error_count" -gt 0 ]; then echo "terraform check failed" exit 1 else echo "terraform check passed" fi

What I observe here is even if the condition fails, the error_count=0 value remains the same. How can I increment the counter on a failing condition?

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
Jenifer
  • 85

1 Answers1

2

As roaima commented, the core of your question boils down to the subshell environment (in (cd ... )) exiting completely, leaving the let "error_count=error_count+1" behind, and not affecting the parent shell's value of error_count.

I would recommend refactoring the code a bit so that you have a reusable function to execute the common functionality and have it return a success or failure code:

#!/bin/bash
terraform_init_and_validate() (
  if    cd "$1" &&
        terraform init -backend=false > /dev/null &&
        terraform validate
  then
        echo "Terraform format check passed successfully in -------> xxx"
        rm -rf .terraform*
        return 0
  else
        echo "Terraform validation failed in xxx"
        cd tmp && rm -rf .terraform*
        return 1
  fi
)

error_count=0 if ! terraform_init_and_validate tmp1 then let "error_count=error_count+1" fi

if ! terraform_init_and_validate tmp2 then let "error_count=error_count+1" fi

echo $error_count if [ "$error_count" -gt 0 ]; then echo "terraform check failed" exit 1 else echo "terraform check passed" fi

The terraform_init_and_validate function runs the code in a subshell, maintaining that isolation for the cd commands, but returns a true or false value depending on the success or failure of the two terraform commands. The main script then calls that function with the two different parameters and increments error_count only if the function returned an error code.

I would also point out a minor discrepancy (to my eyes): that the "success" branch of your code does a rm -rf .terraform* from the initial directory but the "failure" branch does a cd tmp && rm -rf .terraform*, which removes files from a subdirectory of the initial directory.

Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
  • Thanks for the inputs, but if I refactor code like this then if I need to run some pre-steps for let say tmp2 how do I do that ? something like this scenario if executing directory is tmp2 then echo "something" – Jenifer Mar 23 '22 at 15:45
  • Well, I just saw lots of duplicated code, and along with the idea of separating the cd to a subshell, a function sprang to mind. There's always more than one way to do it. Perhaps before calling if ! terraform_init_and_validate tmp2 you insert the code there? – Jeff Schaller Mar 23 '22 at 17:09