90

I've looked around and bit for an answer to this question but I don't seem to find it (which is weird).

My question is, is there any simple way to restart the BASH session from within the terminal on Mac. I just want the same behaviour as if I closed the terminal application and started it again (all variables reset, .bash_profile sourced etc).

I know how to source .bash_profile, but that's not what I want. One of the reasons I want to do this is because a plugin for my BASH prompt has code that prevents colors from being loaded multiple times. Therefore, sourcing .bash_profile doesn't reload the color variables and I have to restart the terminal application to get changes in effect.

4 Answers 4

118

exec bash should replace the current shell process with (a new instance of) bash.

EDIT: Seems from answers below that Catalina replaces bash with zsh. You can run exec zsh in that case, or alternatively exec "$SHELL" which should always use your default shell.

8
  • 2
    Is bash in the terminal application an interactive shell, and does exec bash only restart that interactive shell then? Also, can you explain exactly what the exec command does and it's options? Thanks!
    – Mattias
    Jul 23, 2015 at 15:38
  • exec replaces the current process with a new one. Bash has a very well-written but unfortunately hard to search manpage; type man bash, find the last instance of the string SHELL BUILTIN COMMANDS and then scroll down to exec. In short, passing the -c flag will run it without any environment variables (which might be required for your purposes, I don't know), and the other arguments -l and -a are probably not things you want (they seem to be historical/obscure and specific features). You can also use exec for opening new file descriptors in the current shell, if you leave off the command.
    – Muzer
    Jul 23, 2015 at 15:44
  • 1
    Sorry, yes. I'm not sure about Macs, but in the Linux world at least shells run from a graphical terminal are (usually) not login shells, and you are only restarting the interactive shell and not the terminal itself or your login shell. -l here is an argument to bash and just makes it behave like a login shell. Opening file descriptors in the current shell has nothing to do with your question, but you can use exec 4<>test.txt for example to make file descriptor 4 point to test.txt. Then in the rest of your shell you can do echo test>&4 to output to test.txt.
    – Muzer
    Jul 23, 2015 at 15:57
  • 1
    @Muzer for reasons that I can't say I entirely agree with, OSX has decided that GUI terminal emulators will run login shells.
    – terdon
    Jul 23, 2015 at 18:03
  • 1
    All of these commands still pull in the variables from your parent bash session, thus I do not believe this answer is correct.
    – Constantin
    Aug 8, 2018 at 15:35
18

tl;dr use exec $SHELL if you want the start the same shell you're in. The accepted answer will only work for you if you're using bash.

--

The accepted answer is great for a shell that's using bash, which is also what the OP asked, however, I'm using Terminal on macOS with a non-default shell (zsh) and running the command exec bash obviously doesn't have the desired effect: it launches bash instead of my default shell.

So the environment-agnostic command would be exec $SHELL which utilizes the environment variable $SHELL that stores the default shell for the user.

Also, note that Apple replaced bash with zsh in macOS Catalina so to have the effect the OP is looking for running either exec zsh or exec $SHELL is the way to go after updating to macOS 10.15.

2

According to this article and others your shell doesn't change when you upgrade to Catalina. But any new accounts will be zsh. You can change those to bash if desired. bash will not be part of macOS at some time in the future. Apparently the licensing for zsh is less restrictive.

I came upon this article after getting tired of quitting and restarting iTerm for the same reason as the OP knowing there was a command such as exec zsh.

1

The shortest variant:

$ exec $0
3
  • 1
    Generally won't work on macOS, because terminal tabs are login shells, so $0 will be something like -bash or -zsh, and exec $0 will turn into exec -bash, which will think -bash are options and error out. exec "${0#-}" will get around that, but will replace a login shell with a non-login shell. To replace login with login and non-login with non-login, try this: exec $( [[ "$0" = -* ]] && echo -l ) "${0#-}" Apr 9 at 0:26
  • bash ~ ➜ echo $0 zsh Apr 10 at 9:05
  • I don't understand what you mean by that comment. Apr 10 at 9:33

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.