27

At first this was a bit funny, like playing "Bash Roulette" ...but now it's getting old lol

Any command in my terminal that exits with non-zero code closes my terminal window

I was told that perhaps I have set -e set in some bash script somewhere that my terminal sources.

I have checked .bash_profile / .bashrc / .profile and it doesn't look like set -e is in there.

Would there be any other obvious culprits?

4
  • 8
    Execute a set +e, does it repair the problem? If so, which I assume, then you need to keep looking for that set -e. It could be in the global versions of these files under /etc, or in any other script sourced from them. Move your config files away, if the problem is fixed then add back the lines in smaller chunks to see where it breaks.
    – egmont
    Commented Nov 27, 2017 at 23:21
  • 4
    PS4=' ${BASH_SOURCE}:$LINENO: ' bash -lixc true |& grep -e set -e trap could be informative.
    – muru
    Commented Nov 28, 2017 at 3:23
  • 1
    You can inspect the set of currently enabled shell flags with the special variable - like so: echo $-. Commented Nov 28, 2017 at 12:57
  • What if set +e does not fix the problem? Commented Oct 13, 2023 at 2:30

3 Answers 3

24

Alright, so indeed, it was a wayward set -e that caused my trouble.

The way I found the set -e was using bash -lx

The best thing to do would be to use:

bash -lx > lx.log 2>&1

then open that log file and do a search for set...

once you find that wayward set -e you can remove that line and your problem should be gone! (Machine restart might be a good idea tho).

In my case, the set -e was in a file that .bash_profile sources, but the line was not in .bash_profile itself.

4
  • 4
    Things that are safe to source in your shell is a much smaller set than just "random shell scripts". -e can be useful in actual scripts, for dumb error checking. (Or to make sure you didn't forget to error-check anything.) Commented Nov 28, 2017 at 10:17
  • Apparently that's case...i wish there was something like global set -e so that set -e only affects the containing script Commented Nov 28, 2017 at 15:33
  • @AlexanderMills, to do that, you could check $- to check for the flag in the inner script and restore its state at the end, or just reset it at the main script if you know you have sourced scripts that would set it
    – ilkkachu
    Commented Nov 28, 2017 at 15:39
  • So I guess local set -e could only be used in a bash function? Commented Nov 28, 2017 at 16:14
14

If you just want to solve the problem, include set +e in your .bashrc — at the end.

You can go digging—there are a lot of other places where a set -e might be—but that will take care of the lot.

If, however, the set -e is part of your $PROMPT_COMMAND then the above will not work. Try printf '%s\n' "$PROMPT_COMMAND" and see what's in it.

7
  • 1
    on my machine, when I open a terminal, printf '%s\n' "$PROMPT_COMMAND" yields just whitespace, nothing there Commented Nov 27, 2017 at 23:33
  • @AlexanderMills, then that's not what your problem is. One common use for $PROMPT_COMMAND is to update the terminal tab name or window name; MacOS X and Ubuntu both do this. See apple.stackexchange.com/q/220641/151730 for data on this for Mac.
    – Wildcard
    Commented Nov 28, 2017 at 4:00
  • I found an answer to the problem and added my own answer, set +e didn't work, perhaps because it was before the set -e call in my sourced bash files. Commented Nov 28, 2017 at 5:28
  • 1
    @AlexanderMills, yes, I thought that was implicit. I meant to append set +e to your .bashrc, not put it in at the start. I've made that explicit in my answer now. Good that you found the source!
    – Wildcard
    Commented Nov 28, 2017 at 5:31
  • Yeah, set +e is just a band-aid obviously, but you stated that Commented Nov 28, 2017 at 5:43
2

In my case, the set -e was not in any of my bash startups and appending set +e to my .bashrc was not fixing it.

It turns out the set -e was in a bash script that I frequently run for my project, and I was running that script using . ./my-dev-script.sh so that it would honor my bash aliases.

What I didn't realize is running it with that extra . in front was also causing the bash options in the script to carry over into all my regular terminal sessions.

I need a new solution for running a bash script that honors my personal bash aliases, but at least I found the source of the rogue set -e. Just running it normally with ./my-dev-script.sh prevents the frustrating "Bash Roulette" scenario.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .