Bash Shell – How to Make Explicit Operator Precedence Without Creating a Subshell

bashshellsubshell

I'm sure this is posted somewhere, but I haven't been able to find it.

In Bash, how does one specify operator precedence (aka command grouping) without creating a subshell? In most other languages the() do this, but in Bash this runs the commands in a subshell which "discards" environment changes. I want to specify operator precedence without losing environment changes.

Specifically, I'd like to do something like this and have the entire script exit, not just the subshell in the ():

die ()
{
    echo "[DIE]: $1"
    exit 1
}

# When installChruby returns an error, print the error message and exit
[[ $CHRUBY =~ [Yy] ]] && (installChruby || die "Error installing chruby")

I figured out a "workaround" by doing this, but it's not a pretty one-liner like I want:

if [[ $CHRUBY =~ [Yy] ]]; then installChruby || die "Error installing Chruby"; fi 

The desired outcome is to do nothing and continue if CHRUBY is unset, to call the function installChruby if CHRUBY is either Y or y, and to call the die function only if the installChruby function returns false.

Is there an operator in Bash that does this besides (), or is there a way to tell the code inside the () to not run in a sub-shell?

Best Answer

from man bash:

   { list; }
          list  is  simply executed in the current shell environment.  list must be terminated with a newline or semicolon.
          This is known as a group command.  The return status is the exit status of list.  Note that unlike the  metachar‐
          acters  (  and  ), { and } are reserved words and must occur where a reserved word is permitted to be recognized.
          Since they do not cause a word break, they must be separated from list by whitespace or another shell metacharac‐
          ter.
Related Question