Understanding Shell Initialization Files and User Profiles in Linux
Linux is a multi-user, time sharing system, implying that more than one user can log in and use a system. And system administrators have the task of managing various aspects of how different users can operate a system in terms of installing/updating/removing software, programs they can run, files they can view/edit and so on.
Linux also allows users’ environments to be created or maintained in two major ways: using system-wide (global) and user-specific (personal) configurations. Normally, the basic method of working with a Linux system is the shell, and the shell creates an environment depending on certain files it reads during its initialization after a successful user login.
In this article, we will explain shell initialization files in relation to user profiles for local user management in Linux. We will let you know where to keep custom shell functions, aliases, variables as well as startup programs.
Important: For the purpose of this article, we will focus on bash, a sh compatible shell which is the most popular/used shell on Linux systems out there.
If you are using a different shell (zsh, ash, fish etc..) program, read through its documentation to find out more about some of the related files we will talk about here.
Shell Initialization in Linux
When the shell is invoked, there are certain initialization/startup files it reads which help to setup an environment for the shell itself and the system user; that is predefined (and customized) functions, variables, aliases and so on.
There are two categories of initialization files read by the shell:
- system-wide startup files – theses contain global configurations that apply to all users on the system, and are usually located in the /etc directory. They include: /etc/profiles and /etc/bashrc or /etc/bash.bashrc.
- user-specific startup files – these store configurations that apply to a single user on the system and are normally located in the users home directory as dot files. They can override the system-wide configurations. They include: .profiles, .bash_profile, .bashrc and .bash_login.
Again, the shell can be invoked in three possible modes:
1. Interactive Login Shell
The shell is invoked after a user successfully login into the system, using /bin/login, after reading credentials stored in the /etc/passwd file.
When the shell is started as an interactive login shell, it reads the /etc/profile and its user-specific equivalent ~/.bash_profile.
2. Interactive non-login Shell
The shell is started at the command-line using a shell program for example $/bin/bash or $/bin/zsh. It can as well be started by running the /bin/su command.
When the shell is started in this state, it copies the environment of the parent shell, and reads the user-specific ~/.bashrc file for additional startup configuration instructions.
$ su # ls -la
3. Non-interactive Shell
The shell is invoked when a shell script is running. In this mode, it’s processing a script (set of shell or generic system commands/functions) and doesn’t require user input between commands unless otherwise. It operates using the environment inherited from the parent shell.
Understanding System-wide Shell Startup Files
In this section, we will shade more light on shell startup files that store configurations for all users on the system and these include:
The /etc/profile file – it stores system-wide environment configurations and startup programs for login setup. All configurations that you want to apply to all system users’ environments should be added in this file.
For instance, you can set your the global PATH environment variable here.
# cat /etc/profile
Note: In certain systems like RHEL/CentOS 7, you’ll get such warnings as “It’s not recommended to change this file unless you know what you are doing. It’s much better to create a custom .sh shell script in /etc/profile.d/ to make custom changes to your environment, as this will prevent the need for merging in future updates”.
The /etc/profile.d/ directory – stores shell scripts used to make custom changes to your environment:
# cd /etc/profile.d/ # ls -l
The /etc/bashrc or /etc/bash.bashrc file – contains system-wide functions and aliases including other configurations that apply to all system users.
If your system has multiple types of shells, it is a good idea to put bash-specific configurations in this file.
# cat /etc/bashrc
Understanding User-specific Shell Startup Files
Next, we will explain more concerning user-specific shell (bash) startup dot files, that store configurations for a particular user on the system, they are located in a user’s home directory and they include:
# ls -la
The ~/.bash_profile file – this stores user specific environment and startup programs configurations. You can set your custom PATH environment variable here, as shown in the screenshot below:
# cat ~/.bash_profile
The ~/.bashrc file – this file stores user specific aliases and functions.
# cat ~/.bashrc
The ~/.bash_login file – it contains specific configurations that are normally only executed when you log in to the system. When the ~/.bash_profile is absent, this file will be read by bash.
The ~/.profile file – this file is read in the absence of ~/.bash_profile and ~/.bash_login; it can store the same configurations, which are can also be accessible by other shells on the system. Because we have mainly talked about bash here, take note that other shells might not understand the bash syntax.
Next, we will also explain two other important user specific files which are not necessarily bash initialization files:
The ~/.bash_history file – bash maintains a history of commands that have been entered by a user on the system. This list of commands is kept in a user’s home directory in the ~/.bash_history file.
To view this list, type:
$ history or $ history | less
The ~/.bash_logout file – it’s not used for shell startup, but stores user specific instructions for the logout procedure. It is read and executed when a user exits from an interactive login shell.
One practical example would by clearing the terminal window upon logout. This is important for remote connections, which will leave a clean window after closing them:
# cat bash_logout
For additional insights, checkout the contents of these shell initialization files on various Linux distros and also read through the bash man page:
That’s all for now! In this article, we explained shell startup/initialization files in Linux. Use the comment form below to write back to us.