Writing try catch finally in shell

Solution 1:

Based on your example, it looks like you are trying to do something akin to always deleting a temporary file, regardless of how a script exits. In Bash to do this try the trap builtin command to trap the EXIT signal.

#!/bin/bash

trap 'rm tmp' EXIT

if executeCommandWhichCanFail; then
    mv output
else
    mv log
    exit 1 #Exit with failure
fi

exit 0 #Exit with success

The rm tmp statement in the trap is always executed when the script exits, so the file "tmp" will always tried to be deleted.

Installed traps can also be reset; a call to trap with only a signal name will reset the signal handler.

trap EXIT

For more details, see the bash manual page: man bash

Solution 2:

Well, sort of:

{ # your 'try' block
    executeCommandWhichCanFail &&
    mv output
} || { # your 'catch' block
    mv log
}

 rm tmp # finally: this will always happen

Solution 3:

I found success in my script with this syntax:

# Try, catch, finally
(echo "try this") && (echo "and this") || echo "this is the catch statement!"

# this is the 'finally' statement
echo "finally this"

If either try statement throws an error or ends with exit 1, then the interpreter moves on to the catch statement and then the finally statement.

If both try statements succeed (and/or end with exit), the interpreter will skip the catch statement and then run the finally statement.

Example_1:

goodFunction1(){
  # this function works great
  echo "success1"
}

goodFunction2(){
  # this function works great
  echo "success2"
  exit
}

(goodFunction1) && (goodFunction2) || echo "Oops, that didn't work!"

echo "Now this happens!"

Output_1

success1
success2
Now this happens!

Example _2

functionThrowsErr(){
  # this function returns an error
  ech "halp meh"
}

goodFunction2(){
  # this function works great
  echo "success2"
  exit
}

(functionThrowsErr) && (goodFunction2) || echo "Oops, that didn't work!"

echo "Now this happens!"

Output_2

main.sh: line 3: ech: command not found
Oops, that didn't work!
Now this happens!

Example_3

functionThrowsErr(){
  # this function returns an error
  echo "halp meh"
  exit 1
}

goodFunction2(){
  # this function works great
  echo "success2"
}

(functionThrowsErr) && (goodFunction2) || echo "Oops, that didn't work!"

echo "Now this happens!"

Output_3

halp meh
Oops, that didn't work!
Now this happens!

Note that the order of the functions will affect output. If you need both statements to be tried and caught separately, use two try catch statements.

(functionThrowsErr) || echo "Oops, functionThrowsErr didn't work!"
(goodFunction2) || echo "Oops, good function is bad"

echo "Now this happens!"

Output

halp meh
Oops, functionThrowsErr didn't work!
success2
Now this happens!

Solution 4:

mv takes two parameters, so may be you really wanted to cat the output file's contents:

echo `{ execCommand && cat output ; } || cat log`
rm -f tmp