• How to error proof Bash scripts

    execute () {
        error=$($2 2>&1 >/dev/null)
        if [ $? -ne 0 ]; then
            echo "$1: $error"
            exit 1
  • @es20490446e
    If I’m reading it right, it doesn’t seem to handle possible parameters of a command.
    Could you please show us an example usage?

  • buildApps () {
        execute "buildApps" "yaourt --sync --noconfirm $1"
    buildApps "qtqr xiccd"
  • OK, it is working properly. Very nice! 🙂

    There are three things I’d like to point out, if you have any wishes to develop it further.

    • You are giving all parameters within quotes. If you wish to give them without quotes, that is also possible.
    • If you’d like to get the real error code from “execute()”, that is possible, too.
    • The name of a caller of a function is available.

    So I came up with this:

    execute() {
        local tmpfile=/tmp/errors.$$
        local errorcode
        local errormsg
        "[email protected]" 2>$tmpfile >/dev/null
        if [ $errorcode -ne 0 ] ; then
            if [ -n "${FUNCNAME[1]}" ] ; then
                echo "[called from ${FUNCNAME[1]}]"
            echo -n "$*: "
            cat $tmpfile
            rm -f $tmpfile
            exit $errorcode
            rm -f $tmpfile

    It uses a temporary file to store the error messages (which isn’t ideal but works).
    Use it if you want, or not. I did it just for the fun of it! 🙂

    • Quotes makes possible to handle strings and names with spaces.
    • Exit codes needs a fixed spec.
    • Storing error messages directly into memory is short and efficient.

    Now try to improve the code for real! : P

  • @es20490446e
    Alright, let’s improve it! I made a bash test program to compare implementations (execute vs. runcheck), please run the test.
    See the difference especially in parameter handling?

        "[email protected]" >/dev/null
        local errorcode=$?
        if [ $errorcode -ne 0 ] ; then
            echo "Call stack:"
            local func
            for func in "${FUNCNAME[@]}" ; do
                echo " --> $func"
            echo "Program '$1' fails, error code = $errorcode"
            return $errorcode  # changed 'exit' -> 'return' just for the test below
    execute () {
        error=$($2 2>&1 >/dev/null)
        if [ $? -ne 0 ]; then
            echo "$1: $error"
            return 1   # changed 'exit' -> 'return' just for the test below
        local filename="./a simple test.bash"
        echo "a_non_existing_command" > "$filename"
        chmod u+x "$filename"
        printf "Testing execute:\n"
        execute  "StartTest" "$filename"
        echo $?
        printf "\n\nTesting runcheck:\n"
        runcheck "$filename"
        echo $?
        rm -f "$filename"
    # buildApps using runcheck:
    buildApps() {
        runcheck yaourt --sync --noconfirm "[email protected]"
    # and the call would be:
    # buildApps qtqr xiccd
  • @manuel This one is cool : )

  • @es20490446e
    It is quite a good idea to have a simple way to do a simple, systematic check that a command execution went OK, and immediately stop if something goes wrong.

    In fact I have sometimes done something similar for my small hobby programs, but if you think of a more professional approach, such tools are very useful.

    And while studying this, I found a nice little article about useful settings for bash scripts: http://redsymbol.net/articles/unofficial-bash-strict-mode/

  • @es20490446e
    I suppose those “bash strict mode” settings are meant to be used only when needed (for example in debugging), since they change the “normal” bash script behavior quite much in some aspects. So I’m not using them unless I can see real benefit in using them.

    Anyway, it is good to have various “generic” tools if/when facing problems in programs. : )

  • I think that the ideal is been able to choose which commands should strictly not fail, and which not. In the same script.

    That’s why I like having a function instead of using “set”.

  • @es20490446e
    That’s good for many programs.
    But for some other programs those generic tools/settings are also good.
    Developer just has to know which approach to use. One solution is seldom good for everything.

  • 90% of the time it works every time.

error213 scripts6 bash5 proof1 Posts 13Views 279
Log in to reply
Bloom Email Optin Plugin

Looks like your connection to Antergos Community Forum was lost, please wait while we try to reconnect.