1

I have trouble with error handling in bash scripts. None of the solutions I have seen for error handling in bash seem to work so far for this example script:

#!/usr/bin/env bash
set -euo pipefail

eval $(do_stuff)
touch file

Output is:

./script.sh: line 4: do_stuff: command not found

But even then it happily continues and creates the file, which is what I want to forbid. I figured I can pipe stderr to another program and terminate the whole thing when it grabs some output:

unbuffer ./script.sh 2>&1|{ while read stdin; do echo $stdin;killall -9 bash;done; }

Nevertheless, it works roughly only 5% of the time. In most cases it doesn't manage to kill the script early enough.

  • 1
    Is there any reason you are using eval ? That's "masking" the failed exit code and causing a "success" to be returned to the script, allowing it to continue. – Stephen Harris Sep 3 '16 at 10:20
  • What appears in the body of the script isn't on me, it's written by other developers and this is one use case which caused a fatal error in our system. I want to prevent that in a future. – gadelat Sep 3 '16 at 10:24
  • So what would stop the next developer doing eval "something_wrong 2>/dev/null" ? – Stephen Harris Sep 3 '16 at 10:42
  • That would mean intentional harm. I would like to prevent stupid mistakes. – gadelat Sep 3 '16 at 11:04
1

I figured out how to elegantly handle the case I posted:

eval() {
    if [[ -z "${@}" ]];then
        exit 1
    fi
    builtin eval "$@"
}

It overrides default eval() implementation and exits if it receives no input. I'm not accepting this answer though, because it still doesn't answer the title of this question.

0

Simply change it to assignment first, then eval.

Example 1 (halt if input command invalid):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echoasasas)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 5: echoasasas: command not found
trapped
[xiaobai@localhost ~]$ 

Example 2 (halt if output is not a valid command):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo xxxxx)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
h2.sh: line 6: xxxxx: command not found
trapped
[xiaobai@localhost ~]$ 

Example 3 (continue run next command):

[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
e2=$(echo ls)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
Android  CRITICAL  Documents
next
[xiaobai@localhost ~]$ 

Example 4 (half if STDERR triggered in another shell):

[xiaobai@localhost ~]$ cat /tmp/so.sh 
ls yyyyyy 2>/tmp/kas
[xiaobai@localhost ~]$ cat /tmp/kas
[xiaobai@localhost ~]$ cat h2.sh
#!/bin/bash

trap err_handler ERR
err_handler() { echo trapped ; exit; }
echo "before"
e2=$(/bin/bash /tmp/so.sh)
eval "$e2"
echo "next"
[xiaobai@localhost ~]$ sh h2.sh
before
trapped
[xiaobai@localhost ~]$ cat /tmp/kas
ls: cannot access 'yyyyyy': No such file or directory
[xiaobai@localhost ~]$ 
  • My bad, the above will not works if STDERR happen in the halfway of /bin/bash /tmp/so.sh – 林果皞 Sep 3 '16 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.