Home > Mobile >  How to do a try catch in bash scripts with curly braces?
How to do a try catch in bash scripts with curly braces?

Time:07-08

A recommended pattern that mimics try-catch in bash scripts is to use curly braces. This does not work as expected, though. The following script outputs A B 1. Why is that the case and how must the script be modified to output the intended A C 1?

#!/usr/bin/env bash
set -e

{
  echo "A"
  false
  echo "B"
} || echo "C"

{
  echo "1"
  false
  echo "2"
}

CodePudding user response:

There are many issues with the 'set -e' - it does not work well in many error conditions. This has been covered in many posting, just search 'errexit bash'. For example: Bash subshell errexit semantics

At this time, there is no clean solution. However, there are good news. I'm working on a proposed change that will allow the above to work. See discussion in bash-bug archive: https://lists.gnu.org/archive/html/bug-bash/2022-07/index.html And proposal: https://lists.gnu.org/archive/html/bug-bash/2022-07/msg00006.html

I expect to have the solution submitted for review by the bash dev team this week. Hopefully it will get accepted into next bash release.

It will support new 'errfal' option

set -o errfail
{ echo BEFORE ; false ; echo AFTER ; } || echo "CATCH"

and will output: BEFORE CATCH

If you are looking for more fancy solution consider:

alias try=''
alias catch='||'
try {
    echo BEFORE
    false
    echo AFTER
} catch { echo CATCH ; }

CodePudding user response:

A work-around using 2 separate bash invokations:

bash -c 'set -e; echo "A"; false; echo "B"' || echo 'C'

bash -c 'set -e; echo "1"; false; echo "2"'

Or with intendations:

bash -c '
   set -e
   echo "A"
   false
   echo "B"
' || echo 'C'

bash -c '
   set -e
   echo "1"
   false
   echo "2"
'

Output:

A
C
1

Code Demo

CodePudding user response:

Just use && and remove this dangerous hardly predictable set -e.

#!/bin/sh

{
  echo "A" &&
  false &&
  echo "B"
} || echo "C"

{
  echo "1" &&
  false &&
  echo "2"
}

Test run it

There is never anything wrong with being absolutely explicit in code. Don't count on the implementation to handle even part of the logic.

This is what set -e is doing. Handles some logic for you, and it does it very differently from what you'd expect it to be most of the time.

So be always explicit and handle error conditions explicitly.

  •  Tags:  
  • bash
  • Related