Linux Startup Settings (.bashrc and .bash_profile)
What are the differences between .bashrc and .bash_profile? Why are they required? Where should they be present? What to do in case they are absent in user's home directory? Where are environment variables and path declared in linux? If you are haunted by any of these questions and want to get a solid grasp in no time, you are at the perfect place.
Although you should fully understand this just by reading along, still it is highly recommended to execute the below commands in your own terminal running bash. The commands and concepts presented here are not specific to any particular linux diastro, but are valid in general.
The whole essence of working with Linux is to explore yourself without blindly trusting anyone, not even me! Before executing any command presented in this article, feel free to explore their
man
pages to know their usages and impacts.
High Level Understanding
NOTE: Don't get intimidated if you come across any new/unknown terms in this section. We will go through everything step-by-step while coding in the next section.
Every contents in the file:
.bashrc
are executed when a non-login shell is opened for a user already having an active login session.bash_profile
are executed when a login shell is opened or a new login session is created for a user
There are few things to understand. First, both of these files are specific to a user and are present in the user's home directory. For system wide settings, there are separate files which are beyond the scope of the current discussion and may be platform (diastro) dependent. Next, a non-login shell is obtained whenever you open a new terminal, perform local or remote login to an existing GUI session or switch the current user using su
command without -
, -l
or --login
options. A login shell is obtained whenever you run su
command with the above options or start a new remote login session using ssh
command. For more details, please refer to the man pages of su
and ssh
.
If it is too much for you to digest switch-user and remote logging, a simple takeaway can be to remember that .bash_profile is executed only once when you login for the first time and .bashrc is executed everytime you open a new terminal.
Now, presence of these two files are not absolute necessary. But having them will save us lot's of efforts and help keeping things organized. For example, let's consider you need to have the environment variable JAVA_HOME declared before running a script in terminal. You can always explicitly declare the variable. But having declared that as part of .bashrc will save the effort of declaring it explicitly for new terminals. Moreover, we often need to have multiple environment variables declared for most of the softwares.
Alright! It's now time to get your hands dirty and let the fun begin! Close all other processes running (or wait for them to finish). Open your terminal and switch to the root user. If you need help in switching to root user, check my article Linux: Switch to root user
.
Get a user to experiment with
Not to get messed up with any of the existing user's settings, let's create a new user. Before that, let's verify if we have the bash shell available.
cat /etc/shells
If any of your output ends with bash (in my case, it is /bin/bash), then you are good to go and use that value as login shell in the next command.
NOTE: In this article, we are using username as user1 and it's home directory as /home/user1. You are free to choose your own. But, beware to use your own username and home directory in all the places ahead. If you are a newbie, it is better to copy paste and execute the commands from here.
The following useradd
command creates a new user with the name user1 having home directory at /home/user1 and with login shell /bin/bash. To verify the user is successfully created, run getent
command as below.
useradd -d /home/user1 -s /bin/bash -m user1
getent passwd user1
You should get output similar to
user1:x:10007:10007::/home/user1:/bin/bash
If you get any permission related errors for useradd
command, probably you are not logged in as the root user. To know more about creating users in linux and understanding all the values in the above output, check my article Linux Users and Groups
.
To set password for this user, run
passwd user1
It should ask for entering a new password. Don't worry if you can't see the password you are typing on the screen. Just type your password for user1 and press 'Enter'.
Now that we have the password set, we can switch to that user. Execute
su - user1
Verify if we are logged in with the desired user and are in it's home directory
echo $USER
echo $HOME
pwd
If the output of echo $HOME
and pwd
are same, then you are at the right place.
Edit .bashrc and .bash_profile
Let's append a print statement and a variable declaration at the end of .bashrc and .bash_profile using a text editor. If you don't have these files already created, you can explicitly create them here and have the last two lines from the below snippets inserted. Below are the contents of .bashrc and .bash_profile from my environment. Don't bother if yours look different. Just make sure the last two lines exist.
# .bashrc
# User specific aliases and functions
# Source global definitions
if [ -f /etc/bashrc ]; then
. /etc/bashrc
fi
echo '.bashrc getting called'
my_bashrc_var='My .bashrc variable'
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/bin:/sbin:/usr/sbin
BASH_ENV=$HOME/.bashrc
export BASH_ENV PATH
unset USERNAME
echo '.bash_profile getting called'
my_bash_profile_var='My .bash_profile variable'
If you are more interested to know how to be more productive with .bashrc, check out my article Linux: My .bashrc Content
. For now, let's move on.
To test if you have done your edits properly, let's call both the files explicitly
source .bashrc
source .bash_profile
If you don't get any errors and have the echo statements printed, Congrats! You are all setup for the experiment to begin.
See everything in action
If you have a GUI setup, follow these steps:
-
Logout of the current user.
-
Login with user1
-
Open a terminal
You should see the echo statement that was put in the file .bashrc
. To verify the persistence of variable declaration, run echo $my_bashrc_var
. Amazing! Now you have seen it yourself that .bashrc
is getting called whenever you open a new terminal. If you are wondering about seeing the echo statements in .bash_profile
, I'm sorry! Those were executed in backgroud when you were logging in. It is not impossible to find out the logs, but those are platform(diastro) dependent and beyond the current scope. But hold on, we will definitely look at them using su -
command.
For the next steps, you can again switch back to your default user (other than user1) - logout and login through GUI or use su
command.
-
Open a terminal
-
Execute any one of the below three commands (all are equivalent; for more info, see options in
man su
)
sudo - user1
sudo -l user1
sudo --login user1
Did you see the echo statement in .bash_profile
getting printed? You can execute echo $my_bash_profile_var
to see if the variable is defined. That's it!
NOTE: In some environments, you might be able to see both the echo statements of .bashrc
and .bash_profile
. The reason behind this is that .bash_profile
is set to internally call .bashrc
. If you see the contents of the .bash_profile
posted above, this is exactly what is happening.
If you have made it up to here, you deserve 👏. Now, exit from the session of user1 and relogin using su
command, this time without any option
exit
su user1
You should be able to see the echo statement in .bashrc
. Execute echo $my_bashrc_var
and echo $my_bash_profile_var
. I hope it should be clear by now when the two files get executed and what are the significances.
Clean Up
After all the dirty mess, let's make everything clean as before! To delete the user user1, switch to root user and execute
userdel -rf user1
Protip: It is always a good practice to call .bashrc in your .bash_profile to ensure all the settings for non-login shells are applied to login shells as well. Otherwise, you can explicitly call
source .bashrc
whenever you enter a login-shell.
Protip: In general, always use .bashrc to declare your environment variables and aliases.