Linux·6 min read·

Shell Startup Files Explained: bashrc, profile, Login Shells

Understand when bash sources .bashrc, .profile, and related files so your environment persists across logins.

NB

Netbay Infrastructure Team

Netbay Engineering

On this page

One of the most confusing parts of Linux administration is understanding when and why your shell reads configuration files. You add an alias to .bashrc, log in, and it does not work. You edit PATH in .profile and interactive terminals still miss it. The culprit is almost always the difference between login and non-login shells, and between interactive and non-interactive shells.

Shell Types and What They Source

Bash distinguishes shells along two axes: interactive versus non-interactive, and login versus non-login.

An interactive login shell reads approximately this order:

  1. /etc/profile
  2. The first of ~/.bash_profile, ~/.bash_login, or ~/.profile
  3. The file pointed to by $ENV if defined

An interactive non-login shell reads only ~/.bashrc. This is why SSH logins (which create a login shell) source ~/.profile, while new terminal tabs (non-login) source ~/.bashrc.

A common trap: settings in ~/.profile are available when you SSH in, but a new interactive shell from that session does not automatically re-read them. To keep things consistent, ~/.bash_profile usually sources ~/.bashrc explicitly.

A Clean Layout That Works

A reliable pattern is to keep ~/.bashrc as the single source of truth for interactive settings and have ~/.profile source it for login shells:

bash
# ~/.bashrc
export EDITOR=nano
alias ll="ls -lah"
export PATH="$PATH:$HOME/bin"
umask 022
bash
# ~/.profile
if [ -n "$BASH_VERSION" ]; then
  if [ -f "$HOME/.bashrc" ]; then
    . "$HOME/.bashrc"
  fi
fi

With ~/.profile sourcing ~/.bashrc for bash, every interactive login ends up with the same aliases and PATH as a new terminal tab.

Environment Variables vs Aliases

There is an important distinction between what belongs where. Environment variables that tools and programs expect, like PATH, EDITOR, and LANG, should be exported. Aliases and functions are shell conveniences and only matter for interactive use.

For cron jobs and systemd services, the environment is minimal. Neither ~/.bashrc nor ~/.profile is sourced automatically for cron. If your script depends on special PATH entries, define them inside the script itself:

bash
#!/bin/bash
export PATH="/usr/local/bin:$PATH"
export DB_HOST=localhost

Testing What Gets Sourced

You can inspect which file was sourced and verify your setup:

bash
echo "$0"
bash -l -c 'echo sourced: $0'
env | grep -i path
type ls

$0 shows the name of the running shell. Adding a temporary echo "loaded .bashrc" message in a file lets you observe precisely when it is read during a login.

Non-Interactive Shells and Scripts

Scripts run non-interactively. For a script invoked as bash script.sh, bash does not read ~/.bashrc or ~/.profile at all. If a script runs in your $PATH and you want it to use your environment, use a shebang and call it explicitly, or source the config inside it:

bash
#!/bin/bash
. "$HOME/.bashrc"
myapp --mode prod

This is why the shebang line matters: it tells the system which interpreter to use, and it is the difference between a script that works interactively and one that breaks under cron or systemd.

Which Shell File Gets Sourced? Interactive login SSH session /etc/profile, .profile then .bashrc if sourced Interactive non-login new terminal tab ~/.bashrc only no .profile re-read Non-interactive script bash script.sh sources neither set env internally best practice .profile sources .bashrc verification echo markers + echo $0 cron and systemd give a minimal env: define PATH yourself

Takeaway

The shell startup file system is only confusing until you map which shell type reads which file. Put shared settings in .bashrc, have .profile source it, and keep scripts self-contained. Sort out your shell environment on a Netbay Linux VPS at netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance