107

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.

AdminBee
  • 22,803
Mattias
  • 1,587

5 Answers5

139

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.

Muzer
  • 2,293
  • 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 '15 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 '15 at 15:44
  • Can you show an example of how to use exec for opening new file descriptors in the current shell? And what about my question about interactive/login shell. Is the shell run in the terminal an interactive shell, and is that all the exec command touches. Lastly, this question's approved answer recommend the exec command with the -l flag, but I don't understand what it does. Sorry for asking so much, I just wanna have an understanding of the commands I use. – Mattias Jul 23 '15 at 15:54
  • 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 '15 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 '15 at 18:03
  • 2
    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 08 '18 at 15:35
  • @Constantin as mentioned in a comment above, exec -c will clear the environment before running whatever command you specify. I can edit the answer to add this if you want. – Muzer Aug 08 '18 at 16:27
22

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.

phip
  • 321
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.

Greg
  • 121
2

The shortest variant:

$ exec $0
  • 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#-}" – Simon Kissane Apr 09 '22 at 00:26
  • ~ ➜ echo $0 zsh – user2240578 Apr 10 '22 at 09:05
  • I don't understand what you mean by that comment. – Simon Kissane Apr 10 '22 at 09:33
0

This worked for me:

exec env -i HOME=$HOME bash -l
  • exec replaces the current shell
  • env -i HOME=$HOME resets all existing env vars and sets HOME for the new shell to the old $HOME
  • bash -l starts a new login shell (zsh probably has a similar command)

I added this as an alias and it works fine:

alias reload='echo "Reloading shell...";exec env -i HOME=$HOME bash -l'
rvirk
  • 1