Production Level Knowledge & Tips

  1. 未分類
  2. 3 view

[Shell][Bash]Try Catch Finally

Background

Error handling in Bash is little bit difficult.
But, “set command” and “trap command” help us to do it.

Environment

  • OS
    • Linux 2.6.32-279.el6.x86_64 #1 SMP Fri Jun 22 12:19:21 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux

Content

Try-Catch-Finally

set command reference

trap command reference
#!/bin/bash
function main() {
        trap catch ERR
        echo "[INFO]Main"
        return 0
}

function catch() {
        echo "[ERROR]Fail"
}
function finally() {
        echo "[INFO]Finish"
}

# Entry Point
set -eu
trap finally EXIT
main

The source code result is following.
$ ./main.sh
[INFO]Main
[INFO]Finish
Error handling check.
Add error command to main function and try to run it.
#!/bin/bash
function main() {
        trap catch ERR
        echo "[INFO]Main"
        diff test
        return 0
}

function catch() {
        echo "[ERROR]Fail"
}
function finally() {
        echo "[INFO]Finish"
}

# Entry Point
set -eu
trap finally EXIT
main
Result ist following.
$ ./main.sh
[INFO]Main
diff: missing operand after `test'
diff: Try `diff --help' for more information.
[ERROR]Fail
[INFO]Finish

Retry

Easy to add retry function with inserting “main” catch function.
#!/bin/bash
function main() {
        trap catch ERR
        echo "[INFO]Main"
        return 0
}

function catch() {
        echo "[ERROR]Fail"
        echo "[INFO]Retry"
        main

}
function finally() {
        echo "[INFO]Finish"
}

# Entry Point
set -eu
trap catch ERR
trap finally EXIT
main
Let’s check error handling part with following program which has an error.
#!/bin/bash
function main() {
        trap catch ERR
        echo "[INFO]Main"
        diff test
        return 0
}

function catch() {
        echo "[ERROR]Fail"
        echo "[INFO]Retry"
        main

}
function finally() {
        echo "[INFO]Finish"
}

# Entry Point
set -eu
trap catch ERR
trap finally EXIT
main
Result is following.
$ ./main.sh
[INFO]Main
diff: missing operand after `test'
diff: Try `diff --help' for more information.
[ERROR]Fail
[INFO]Retry
[INFO]Main
diff: missing operand after `test'
diff: Try `diff --help' for more information.
[INFO]Finish

unit test

You can write unit test with this structure easily.
shunit2 will help you. Concrete source code is following.

main.sh

#!/bin/bash
function main() {
        trap catch ERR
        echo "[INFO]Main"
        lib_main
        return 0
}
function catch() {
        echo "[ERROR]Retry"
        main
}
function finally() {
        if [ ! $? -eq 0 ]; then
                TITLE="error"
                TO=abc@example.com
                FROM=abc@example.com
                echo -e "Please check log file." | mail -s "$TITLE" -r "$FROM" "$TO"
                echo "[ERROR]Alert mail is sent to $TO ."
        fi

        echo "[INFO]Finish"
}

# Entry Point
SOURCE_PATH="$(cd $(dirname $0);pwd)"
source $SOURCE_PATH/lib.sh
set -eu
trap finally EXIT
main

lib.sh

#!/bin/bash
function lib_main() {
        echo "[INFO]Lib Main"
        touch "test.log"
        return 0
}

test.sh

#!/bin/bash
function oneTimeSetUp() {
  echo "[INFO]Setup"
  source ./lib.sh
}
function testLibMain() {
  lib_main
  test -e test.log
  ${_ASSERT_EQUALS_} "TestFileExists" $? 0
}
. "path/to/shunit2/shunit2"
main.sh result is following.
$ ./main.sh
[INFO]Main
[INFO]Lib Main
[INFO]Finish
test.sh result is following.
[INFO]Setup
testLibMain
[INFO]Lib Main

Ran 1 test.

OK

Conclusion

You can add error handling and retry function to Bash script with “set command” and “trap command”

未分類 recent post

  1. Install sbt 1.0.0 and run sample template

  2. Visualization of Neural Network and its Train…

  3. [Machine Learning]Created docker image includ…

  4. [Node.js]How to write batch script with Node.…

  5. [Hive]Get top n items for each category

関連記事

PAGE TOP