To make an alias for the Terminal in OS X, you can either put the aliases in .bash_profile
or .bashrc
. What is the difference between the two and why would I choose to put aliases in one and not the other?
5 Answers
.bash_profile
is executed for login shells, while .bashrc
is executed for interactive non-login shells.
When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile
is executed to configure your shell before the initial command prompt.
But, if you’ve already logged into your machine and open a new terminal window (xterm) then .bashrc
is executed before the window command prompt. .bashrc
is also run when you start a new bash instance by typing /bin/bash
in a terminal.
On OS X, Terminal by default runs a login shell every time, so this is a little different to most other systems, but you can configure that in the preferences.
-
109
On OS X, Terminal by default runs a login shell every time
- I have always been so confused by not realizing this. Great info!– vaughanSep 6, 2017 at 12:18 -
7I'm on OS X and I use zshell instead of bash, and iTerm instead of Terminal. Despite the fact that I'm using a different terminal and a different shell than the answer discusses, OS X still seems to be considering everything a login shell, because
.zprofile
gets ran every time. Jan 16, 2018 at 17:33 -
4For those looking for a thorough explanation of the combinations of login/non-login and interactive/non-interactive shells and when they run these config files, see unix.stackexchange.com/a/46856/38715 May 28, 2018 at 20:20
-
This is a really good answer. It helped me understand why I always need to do a manual step after installing RVM on Ubuntu or Fedora to get it to work, where I cut and paste the line
[[ -s "$HOME/.rvm/scripts/rvm" ]] && source "$HOME/.rvm/scripts/rvm" # Load RVM into a shell session *as a function*
from~/.bash_profile
to~/.bashrc
. RVM seems to install itself as if it were always being installed on a Mac. It assumes that every time a terminal is started, it will be a login shell. If you use your computer differently, where you only log in once, you need to tweak things. Mar 20, 2022 at 21:33 -
It should be noted, that a new Terminal.app window or tab will look for and source
~/.bash_profile
or~/.profile
as mentioned, but if you spawn a new bash using something likeexec bash
orbash
from that the new window/tab, it will only seek and source~/.bashrc
. To avoid that, useexec bash -l
orbash -l
to spawn the new bash as a 'login' shell, which will then look for.bash_profile/.profile
. Same for new windows created within tmux/screen, they will only source~/.bashrc
. Apr 15, 2022 at 1:27
X11 will look at your .bashrc
while a "regular" Terminal will look at .bash_profile
However, if you add the following to your .bash_profile
, you can then move everything into your .bashrc
file so as to consolidate everything into one place instead of two:
if [ -f $HOME/.bashrc ]; then
source $HOME/.bashrc
fi
-
-
7These 2 configuration files have a clearly separate function. In some cases, it is necessary to have things to initialize at the beginning of session and only there (
~/.bash_profile
). It is also often necessary to have things to define incrementaly at every shell level (~/.bashrc
). It isn't the best idea to suggest to suppress this freedom.– danSep 23, 2013 at 14:20 -
4@danielAzuelos: Lurch left this part out, but the OS X Terminal sources
~/.bash_profile
for every new window/tab, so there's not really a way to separate the two as far as Terminal is concerned.– mipadiJan 28, 2014 at 0:28 -
21@mipadi There is still value to separate them. For example,
.bash_profile
can never be sourced again in child process. Every level of nested Bash sources.bashrc
, so if you put something likeexport A=a:$A
in.bashrc
, your$A
will get longer in nested Bash. I typically leave environment variable in profile, and aliases in RC. Nov 1, 2017 at 23:29 -
1One issue with this. When you run
source .bashrc
in Terminal havingif [ -f $HOME/.bashrc ]; then source $HOME/.bashrc fi
in.bash_profile
duplicates whatever paths you have added in.bashrc
.– JohnApr 1, 2020 at 4:34
For macOS, the code to put into .bash_profile
to consolidate everything into .bashrc
is the following:
if [ -f ~/.bashrc ]; then
source ~/.bashrc
fi
This is more specific for Mac terminal user.
-
19
TLDR; use .bash_profile
for your aliases.
The way the different initialisation files work together is a bit more complicated, and there are some important special cases in OSX. Here are the highlights:
- Bash, on any platform, executes one of several different files depending on how it is invoked. The details are here.
- OSX's Terminal App does something non-standard: it creates every new tab or window as if it were a login shell, which means that
.bash_profile
is called. Thus the TLDR advice above. .bashrc
is also an option, but that will be called every time you create a subshell (i.e., invokebash
), which can create inefficiency if you update a variable within it (e.g.,PATH=/bin/foo:$PATH
)- Other apps that have embedded terminals can choose to follow Terminal App's convention or not. Notably, Visual Studio Code, by default, does not.
- Apps invoked via the GUI are not spawned from a shell. Thus, there are several competing mechanisms for setting environment variables for them to see, which have changed over the years.
- Snippets that call
.bashrc
from.bash_profile
are quite common.
-
1Why exactly is using
.bash_profile
for aliases complicated? The items you list only partially are about aliases at all, so instead of just listing some bullets which might explain why it seems to be complicated can you maybe propose a way to make it easier within these constraints?– nohillside ♦Aug 12, 2019 at 5:21 -
I see your point. It is not that using .bash_profile is complicated. It is that the way the files is invoked is complicated. I'll update.– LeoAug 12, 2019 at 5:27
-
1Calling .bashrc from .bash_profile is recommended in the GNU bash manual - otherwise how do you set variables etc that you need both in login shells and non intereactive ones?– mmmmmmAug 14, 2019 at 6:53
-
Every terminal emulator that I use on different OS's has an option to run new windows as a login shell, xterm and Xfce to name just two.– fd0Aug 14, 2019 at 11:03
For ubuntu/debain I add this code at the end of .bashrc
:
if [ -f ~/.bash_profile ]; then
source ~/.bash_profile
fi
Now my aliases take effect in all new opened terminals(or tabs)
brew install bash
and use iTerm2, you could setprofile -> command
to/usr/local/bin/bash
which will load.bashrc
by default after.bash_profile
. This also gives you Bash 4 goodies....bash_profile
, that is because with macOS Catalina switched frombash
tozsh
; therefore now you have to use.zprofile
instead of.bash_profile
.