What I Learned Today 💡 June 8, 2017

.bashrc VS .profile VS .bash_profile

The presence and (somewhat) similar usage of these three files has always confused me. Recently, though, I came across this post on superuser-stackexchange that clarified the differences quite well.

.bashrc

Stands for bash r un- c ommands.

un- ommands. For configurations specific to bash , as opposed to your entire shell session (which would include things like startup programs and environment variables ) .

, as opposed to your entire shell (which would include things like and ) You should put things here for when you’re using bash interactively . E.g. using bash like normal — you type into the terminal, bash reads your input from STDIN, bash processes your command, then spits out the output to STDOUT.

Contrast this to a non-interactive bash , such as using bash in the form of: bash -c "<commands here>" . In this usage, a new instance of bash spawns, executes the commands given, then dies/returns with the output. There isn’t any interactivity in this scenario.

. — you type into the terminal, bash reads your input from STDIN, bash processes your command, then spits out the output to STDOUT. Contrast this to a , such as using bash in the form of: . In this usage, a new instance of bash spawns, executes the commands given, then dies/returns with the output. There isn’t any interactivity in this scenario. E.g. aliases , function definitions , shell options , and shell-prompt settings .

, , , and . .bashrc is automatically executed ONLY when the shell is

1) Interactive

2) NOT A LOGIN SHELL.

.profile

For session-relevant configurations such as startup programs and environment variables .

and . Introduced with the original Bourne shell . Used as a backup default for modern shells such as bash , zsh, and fish . In this sense, it is shell-agnostic.

. Used as a default for modern shells such as , and . In this sense, it is .profile is automatically executed when the shell is

1) A Login Shell.

.bash_profile

Specific to bash .

. If both .bash_profile and .profile are present, and you login to a bash instance, then .bash_profile has priority .

and are present, and you to a bash instance, then . .bash_profile is automatically executed when the shell is

1) A Login Shell.

2) Bash.

When each file is executed — Demo Videos

I mentioned that each of the three files are executed under specific circumstances. I will further demonstrate this with gifs.

.bashrc

In this video:

I demonstrate that my .bashrc has 1 statement: echo '.bashrc has executed!' I close my terminal. I open my terminal (which also logs into bash). '.bashrc has executed' does not show up. Meaning that it didn’t execute upon login. I start another, sub-instance of bash in interactive mode. '.bashrc has executed' does show up. Meaning that it was executed.

This illustrates that .bashrc will execute in an interactive shell, but not if it’s a login shell.

.profile (no .bash_profile )

In this video:

I demonstrate that my .profile has 1 statement: echo '.profile has executed!' I demonstrate that .bash_profile does not exit. I close my terminal. I open my terminal (which also logs into bash). '.profile has executed!' does show up. Meaning that it was executed upon login.

This illustrates that .profile will execute in a login shell. The next video will demonstrate that it will not execute if .bash_profile exists.

.profile (with .bash_profile )

Like I said, .bash_profile takes precedence over .profile on bash, so .profile is not executed when .bash_profile exists.

.bash_profile

Same sort of deal here. Note that .profile does exist still, but it wasn’t executed because .bash_profile takes precedence over .profile when on bash.

Wat do?

The general advice is that you should use .profile and .bashrc as described above, then create a .bash_profile that loads those two files, and does nothing else.

Such as the following:

# Apply config of ~/.profile in the current shell,

# if it exists.

if [[ -r ~/.profile ]]

then

source ~/.profile

fi # Apply config of ~/.bashrc in the current shell,

# if it exists.

if [[ -r ~/.bashrc ]]

then

source ~/.bashrc

fi

Opinions expressed in these articles do not reflect those of my employer.