Understanding Which Dotfiles Different Shells Source On Login
What Shell Startup Files Do on Login
When a user logs into a Unix-based system, the login shell executes various startup files that initialize the shell session. The startup files that get loaded depend on the shell in use and whether it is a login or interactive session.
.profile, .bash_profile, .bashrc – Purpose and Order of Execution
For Bash, the common startup files are:
- .bash_profile – Executed for login shells
- .bashrc – Executed for interactive non-login shells
- .profile – Executed for login shells if .bash_profile not found
On login, .bash_profile is first searched for and executed if found. If not, then .profile is executed. The .bash_profile file typically loads the .bashrc file using the source command so settings there also take effect.
Zsh and Other Shells – Alternate Startup Files Loaded
For the Z shell (zsh), common startup files are:
- .zprofile – Executed for login shells
- .zshrc – Executed for interactive shells
- .zlogin – Executed for login shells if .zprofile not found
The Z shell starts similarly first looking for .zprofile on login shells, followed by .zlogin, and loading .zshrc on interactive invocations.
Other shells like tsch and fish have their own initialization scripts. The fish shell for example sources ~/.config/fish/config.fish.
Configuring your $PATH
The $PATH environment variable specifies directories searched for commands executed by the user. To add a directory to $PATH to make utilities there accessible:
export PATH="$PATH:/your/bin/path"
This typically goes in shell startup files like .profile or .bashrc.
Setting Environment Variables
Environment variables can be set similarly to configure aspects of the user environment. For example to set an EDITOR var:
export EDITOR=vim
Modified environment variables will be visible in child processes spawned from that shell.
Customizing your Prompt
You can customize your shell prompt by setting the PS1 variable in Bash:
export PS1="\u@\h $ "
Or PROMPT in Zsh:
PROMPT='%n@%m %1~ $ '
This lets you add colors, timestamps, usernames, working directories etc.
Sourcing External Scripts
You can break up shell customizations into multiple files and source them from startup scripts:
# In .zshrc source ~/.shell-aliases source ~/.shell-functions
This keeps individual config files purpose focused.
Common Files Loaded on Login
.bashrc
The .bashrc file contains Bash initializations executed for interactive non-login shells. It commonly sets aliases, functions, environment variables, and prompts.
.zshrc
The Z shell .zshrc serves a similar purpose to .bashrc, initializing interactive shell invocations with plugins, completion, themes, aliases etc.
.profile
The .profile startup script initializes login shells in environments without a .bash_profile, across various Unix shells like Bash, Zsh etc. It handles $PATH, vars, terminal settings.
.bash_profile
In Bash, .bash_profile is executed specifically for login shells and usually sources files like .bashrc and .profile to apply settings in non-login children processes.
When Each File is Loaded
Interactive vs Non-Interactive Shells
An interactive shell reads commands from user input, while a non-interactive shell executes a script.
Startup files like .bashrc and .zshrc initialize interactive shells, while scripts for non-interactive shells source utilities as needed.
Login vs Non-Login Shells
A login shell begins on initial session start, executed with your username. Non-login shells are child processes spawned from the login shell.
Files like .bash_profile and .zprofile are invoked for login shells. .bashrc and .zshrc configure non-login children shells.
Example Bash Startup File Contents
Setting Aliases, PATH variables
# .bash_profile # Get current PATH export PATH=$(echo $PATH | sed 's/:\$//') # Append custom bins export PATH="$PATH:/Users/foo/bin:/opt/bin" # Set host specific vars if [[ "$HOST" == "workstation" ]]; then export WORK_VARS=true fi # Set aliases alias c='clear' alias ..='cd ..' # Source .bashrc for interactive shells if [-f ~/.bashrc ]; then source ~/.bashrc fi
Example Zsh Startup Configuration
Initializing Zsh Plugins, Themes, Completion
# .zshrc # Load zsh add-ons source ~/.zsh/zsh-autosuggestions/zsh-autosuggestions.zsh # Apply themes ZSH_THEME="powerlevel10k/powerlevel10k" # Plugin config plugins=( git sudo history command-not-found zsh-syntax-highlighting ) # Completion config autoload -Uz compinit && compinit
Overriding Defaults for Specific Shell Sessions
Bypassing .zshrc with ‘zsh -f’
The -f option starts Zsh without sourcing startup files like .zshrc:
zsh -f
This provides a clean shell environment overriding your settings.
Using another .bashrc with ‘bash –rcfile’
You can have Bash execute an alternate startup file for that session:
bash --rcfile ~/.otherbashrc
This lets you test new configs separately from your main .bashrc.