.bashrc vs .bash_profile: What is the Difference?

When you open a terminal or log in to a Linux system, Bash reads and executes commands from a set of startup files. These files let you customize your shell environment: creating aliases
, adding directories to $PATH
, setting environment variables
, and changing the shell prompt.
Which startup file Bash reads depends on whether the shell is a login or non-login shell. This guide explains the difference between .bashrc and .bash_profile, when each file is loaded, and where to put your customizations.
Interactive vs Non-Interactive Shells
A shell can be either interactive or non-interactive:
- Interactive shell - A shell that reads input from the user and writes output to the terminal. This is what you use when you type commands at a prompt.
- Non-interactive shell - A shell that runs without user interaction, such as when executing a Bash script
. Non-interactive shells do not read
.bashrcor.bash_profile, with one exception for commands run over SSH that is covered below.
Login vs Non-Login Shells
An interactive shell can be either a login or a non-login shell:
- Login shell - Invoked when you log in to the system. This includes logging in via SSH
, logging in at a local console, or starting Bash with the
--loginoption. - Non-login shell - Invoked when you open a new terminal window or tab in a graphical desktop, or when you type
bashinside an existing shell.
You can check whether your current shell is a login shell by running:
shopt login_shellIf the output is login_shell on, it is a login shell. If it is login_shell off, it is a non-login shell.
Startup File Loading Order
When Bash starts as an interactive login shell, it reads the following files in order:
/etc/profile- System-wide settings. This file usually sources scripts from/etc/profile.d/.~/.bash_profile- User-specific login settings. If this file does not exist, Bash looks for~/.bash_login, then~/.profile, and executes commands from the first one it finds.
When a login shell exits, Bash reads and executes commands from ~/.bash_logout, if it exists. This is where cleanup commands go, such as clearing the screen or removing temporary files.
When Bash starts as an interactive non-login shell, it reads:
/etc/bash.bashrc- System-wide settings for interactive shells on Debian and Ubuntu. These distributions patch Bash to read this file, which is not upstream Bash behavior. Fedora and RHEL use/etc/bashrcinstead, and that file is sourced from the default~/.bashrcrather than read by Bash itself.~/.bashrc- User-specific shell settings.
The following table summarizes which files are read in each scenario:
| Shell Type | Files Read |
|---|---|
Interactive login (SSH, console, bash --login) | /etc/profile → ~/.bash_profile (or ~/.bash_login or ~/.profile) |
Interactive non-login (new terminal tab, typing bash) | Debian/Ubuntu: /etc/bash.bashrc → ~/.bashrc; Fedora/RHEL: ~/.bashrc → /etc/bashrc |
| Non-interactive (scripts) | None (unless BASH_ENV is set) |
Non-interactive over SSH (ssh host command) | ~/.bashrc |
Difference Between .bashrc and .bash_profile
.bash_profile is executed for each login shell. .bashrc is executed for interactive non-login shells and for some non-interactive Bash sessions started by a remote shell daemon.
In practice, most users want their interactive customizations to be available in both login and non-login Bash shells. The standard approach is to put those customizations in ~/.bashrc and have ~/.bash_profile source it:
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fiWith this setup, interactive login and non-login Bash shells load the same configuration.
Where to Put What
| Customization | File | Reason |
|---|---|---|
| Aliases | ~/.bashrc | Available in every interactive shell |
| Shell functions | ~/.bashrc | Available in every interactive shell |
Prompt customization (PS1) | ~/.bashrc | Applied to every new shell |
$PATH modifications | ~/.bash_profile or ~/.profile | Set for a login session and inherited by its child processes |
Environment variables (export) | ~/.bash_profile or ~/.profile | Available to programs started from the login session |
| Commands to run once at login | ~/.bash_profile | Run only during login (e.g., ssh-agent, startup messages) |
.profile vs .bash_profile
Many Linux distributions use ~/.profile instead of ~/.bash_profile. The difference is:
~/.bash_profile- Read only by Bash.~/.profile- Read by Bash and other POSIX-compatible shells (sh, dash).
If both ~/.bash_profile and ~/.profile exist, Bash reads only ~/.bash_profile and ignores ~/.profile. If you want ~/.profile to be read, either remove ~/.bash_profile or source ~/.profile from within it.
Ubuntu and Debian create ~/.profile by default and do not create ~/.bash_profile. Fedora and RHEL create ~/.bash_profile.
macOS Note
On macOS, Terminal.app and iTerm2 open login shells by default, which is the opposite of most Linux terminal emulators. This means ~/.bash_profile (or ~/.zprofile for zsh) is read every time you open a terminal window on macOS.
Since macOS Catalina (2019), the default shell on macOS is zsh, not Bash. The zsh equivalents are:
| Bash File | Zsh Equivalent |
|---|---|
~/.bash_profile | ~/.zprofile |
~/.bashrc | ~/.zshrc |
If any of these startup files do not exist on your system, you can create them .
Quick Reference
For a printable quick reference, see the Bash cheatsheet .
| File | When Loaded | Use For |
|---|---|---|
/etc/profile | Login shells | System-wide environment settings |
~/.bash_profile | Login shells | User login settings, sourcing .bashrc |
~/.profile | Login shells (if no .bash_profile) | Portable user login settings |
~/.bashrc | Interactive non-login shells and non-interactive Bash started by a remote shell daemon | Aliases, functions, prompt, and remote-command settings placed before any interactivity guard |
/etc/bash.bashrc (Debian/Ubuntu) or /etc/bashrc (Fedora/RHEL) | Non-login interactive shells | System-wide shell settings |
~/.bash_logout | Login shell exit | Cleanup commands run at logout |
Troubleshooting
Aliases do not work when connecting via SSH
SSH opens a login shell, which reads ~/.bash_profile but not ~/.bashrc. Add . ~/.bashrc inside your ~/.bash_profile so that aliases are loaded in login shells as well.
Remote SSH commands cannot find a programssh user@host opens an interactive login shell that reads ~/.bash_profile. When the user’s login shell is Bash, running ssh user@host 'command' starts a non-interactive shell that reads ~/.bashrc. The default .bashrc on Debian and Ubuntu returns at the interactivity guard near the top of the file, while the Fedora and RHEL default continues through the file. If a remote command needs a PATH change on a system with this guard, place only the required export statement above it and keep aliases, prompts, and other interactive settings below it.
PATH changes in .bashrc are not applied
Put login-session PATH changes in ~/.bash_profile or ~/.profile. If you intentionally keep an interactive-only PATH change in ~/.bashrc, make sure ~/.bash_profile sources that file so interactive login shells receive it.
Changes to .bashrc do not take effect
After editing ~/.bashrc, either open a new terminal or run source ~/.bashrc to apply the changes in the current shell.
Both .bash_profile and .profile exist but only one is used
If ~/.bash_profile exists, Bash ignores ~/.profile. Either consolidate your settings into one file or have ~/.bash_profile source ~/.profile.
FAQ
Which file should I edit to add an alias?
Add aliases to ~/.bashrc. As long as ~/.bash_profile sources ~/.bashrc, your aliases will be available in interactive login and non-login shells.
Why does my terminal not read .bash_profile?
Most Linux terminal emulators (GNOME Terminal, Konsole, xfce4-terminal) open non-login shells, which read ~/.bashrc instead of ~/.bash_profile. Only SSH sessions, console logins, and bash --login trigger a login shell.
What is the difference between source and .?
They are equivalent. Both execute commands from a file in the current shell. . ~/.bashrc and source ~/.bashrc do the same thing. The . syntax is POSIX-compatible, while source is a Bash extension.
Does .bashrc run when I execute a script?
Not for a local script. Scripts run in a non-interactive shell, which does not read ~/.bashrc unless the script explicitly sources it or the BASH_ENV variable is set to point to it. There is one exception: when Bash detects that its standard input is connected to a network connection, as with ssh user@host 'command', it reads ~/.bashrc even though the shell is not interactive. Debian and Ubuntu place the following interactivity guard at the top of the default ~/.bashrc:
# If not running interactively, don't do anything
case $- in
*i*) ;;
*) return;;
esacWhere should I put environment variables for GUI applications?
GUI applications do not read .bashrc or .bash_profile. On systemd-based systems, put environment variables in ~/.config/environment.d/*.conf or set them in your desktop environment settings.
Conclusion
.bash_profile is read by login shells, while .bashrc is read by interactive non-login shells and certain remote non-interactive Bash sessions. Put interactive customizations in ~/.bashrc, source it from ~/.bash_profile, and keep login environment settings in ~/.bash_profile or ~/.profile.
Tags
Linuxize Weekly Newsletter
A quick weekly roundup of new tutorials, news, and tips.
About the authors

Dejan Panovski
Dejan Panovski is the founder of Linuxize, an RHCSA-certified Linux system administrator and DevOps engineer based in Skopje, Macedonia. Author of 800+ Linux tutorials with 20+ years of experience turning complex Linux tasks into clear, reliable guides.
View author page