-3

I'd like to use set -e in a bash script, but every time I run it any error kills my shell.

  say I have script.sh:

  #! /usr/bin/env bash
  set -e
  my_commmand
  my_other_command

An error in my_command blows up my shell whether I do:

 % ./script.sh (after chmod)

or

 % . ./script.sh

There must be an easy way around this.

  • 1
    Using set -e inside a script is not supposed to terminate your shell if you invoke it as ./script.sh. Are you sure that's actually happening as you describe? Can you try to build a small reproducible example that demonstrates it? Are you sure you don't already have set -e on your shell? (You can disable it with set +e and you can see which options are set with echo $-). Good luck! – filbranden May 23 '18 at 18:42
  • 1
    Patient: "Doctor, it hurts when I do (this)"; Doctor: "Well, stop doing (that)" -- are you sure you really need/want to use set -e – glenn jackman May 23 '18 at 18:57
4

Do you mean that your interactive shell exits?

If you source a script (with .) that sets set -e from your interactive shell, the "exit-on-error" flag will also be set in your interactive shell. If you've done that before, then it will apply to any command you run afterwards, be it a sourced script (. ./script.sh), or one started normally (./script.sh).

The solution is to not source scripts that set -e.

You may also want to see BashFAQ 105 on other issues with set -e.

  • That's why I thought executing it would not kill the shell, but that kills the shell too. – Ray Salemi May 23 '18 at 18:24
  • 3
    @RaySalemi, what I mean is that if you run . ./script.sh, and it succeeds, then set -e will be in effect in your interactive shell. Afterwards, running ./script.sh would trigger the error exit if the script now failed. Either it's that, or you have set -e in some of the shell's startup files. But just running that script normally, will not exit the main interactive shell. – ilkkachu May 23 '18 at 18:28
  • But should ./script.sh kill the shell? I thought it should not – Ray Salemi May 23 '18 at 21:57
  • @RaySalemi It will not. But, if you have previously run . ./script.sh this would enable set -e in the interactive shell. A failure in script.sh when running it as ./script.sh would then kill the interactive shell. – Kusalananda May 24 '18 at 9:38
0

If you want to have set -e in an interactive shell, and want to execute a command which may return nonzero, you need to catch that exit code. One method:

$ some_command || :

Another:

$ if ! some_command; then :; fi
0

If you did ever call set -e in your login shell and then run a command that returns a non-zero exit code that is not used in a compound statement, then your login shell will exit:

set -e
false

will log you out.

If you did ever run a script that includes set -e using . ./script you did set -e in your login shell.

If you later run any command with non zero exit code: bingo.

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.