プログラミング + アカデミック + 何か面白いこと

  1. Programming
  2. 454 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”.

デスクの横に置いておいて、困ったときにパラパラめくる辞書のように使えるので割と便利。

Programming recent post

  1. Install sbt 1.0.0 and run sample template

  2. [Machine Learning]Created docker image includ…

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

  4. [Play][Scala]Develop Request Driven Batch Usi…

  5. [OpenCV][Ruby]Auto check web page design corr…

関連記事

PAGE TOP