Get AI summaries of any video or article — Sign up free
Customizing Your Terminal: .bash_profile and .bashrc files thumbnail

Customizing Your Terminal: .bash_profile and .bashrc files

Corey Schafer·
4 min read

Based on Corey Schafer's video on YouTube. If you like this content, support the original creators by watching, liking and subscribing to their content.

TL;DR

Interactive terminal tweaks (like setting PS1) apply only to the current shell session and reset on restart.

Briefing

Custom terminal settings only “stick” when they’re placed in the right startup files—specifically the dotfiles in a user’s home directory: .bash_profile and .bashrc. Typing changes like PS1=... can update the prompt immediately, but they vanish when the terminal is closed and reopened. The practical fix is to edit these files so the shell applies preferences every time a new session starts, including when connecting remotely via SSH.

The workflow starts by locating the dotfiles (ls won’t show them unless dotfiles are included). If .bash_profile or .bashrc don’t exist, they can be created. To demonstrate the difference between the two, the transcript temporarily moves the existing .bash_profile and .bashrc out of the way, confirming that previously added customizations—like prompt color changes and Git-related display—no longer appear. Recreating the files then makes it clear which one runs under which circumstances.

On macOS, opening a new terminal session triggers a login shell, which runs commands from .bash_profile. In contrast, .bashrc does not run during that initial login-shell startup. However, .bashrc does run when starting a non-login shell (or a subshell). The transcript shows this by adding echo statements to each file: reopening the terminal prints the .bash_profile message but not the .bashrc message; running bash to spawn a subshell prints the .bashrc message.

Because login shells and non-login shells behave differently, many users end up duplicating configuration. A cleaner approach is to centralize customizations in .bashrc and have .bash_profile delegate to it. The method is a small conditional in .bash_profile that checks whether .bashrc exists and then sources it (i.e., executes its contents in the current shell). In effect, every time a login shell starts, .bash_profile runs first, then immediately loads .bashrc; and when a subshell starts, .bashrc runs directly. That structure ensures the same prompt and other settings apply consistently across shell types.

Once this wiring is in place, changes made to .bashrc—such as setting PS1 to a custom prompt—persist across both fresh terminal launches and subshells. The result is a single “home” for terminal customization, setting up the foundation for later improvements like aliases, Git branch prompts, Git autocompletion, and environment variable exports (including PATH adjustments). The key takeaway is that correct file placement and sourcing logic determine whether terminal customization is temporary tinkering or reliable daily workflow.

Cornell Notes

Terminal prompt and environment tweaks made interactively (like setting PS1) disappear after the terminal closes. Persistent customization requires editing startup dotfiles in the home directory: .bash_profile for login shells and .bashrc for non-login shells/subshells. On macOS, new terminal windows run .bash_profile, while .bashrc runs when starting a subshell (e.g., running bash). To avoid maintaining two separate configurations, .bash_profile can conditionally source .bashrc when it exists, so one file controls both login and non-login behavior. After this setup, changes to .bashrc (including a custom PS1 prompt) apply consistently across terminal sessions and subshells.

Why do changes to the prompt made directly in a terminal (e.g., PS1=...) not persist?

They apply only to the current running shell process. When the terminal is closed, that shell exits, and the next time a new shell starts it reinitializes from startup files. Without editing .bash_profile and/or .bashrc, the next session uses the default prompt settings again.

What’s the practical difference between .bash_profile and .bashrc in this workflow?

The transcript distinguishes them by shell type. .bash_profile runs for a login shell (the startup path used when opening a new terminal session on macOS). .bashrc runs for non-login shells and subshells—demonstrated by adding echo statements and then starting a subshell with bash, which triggers the .bashrc output.

How can a user verify which file runs when?

Add a visible command like echo to each file, then reopen the terminal. If only the .bash_profile echo appears, the session is using a login-shell startup. If running bash triggers the .bashrc echo, that confirms .bashrc is executed for subshells/non-login shells.

How does sourcing .bashrc from .bash_profile unify configuration?

In .bash_profile, add a conditional that checks whether .bashrc exists and then sources it (executes its contents). The logic is: if .bashrc exists, run source .bashrc; otherwise do nothing. This makes login shells load .bashrc automatically, while subshells still load .bashrc directly.

What does this unified setup enable for daily customization?

It lets users maintain one customization file (.bashrc) for prompt settings and other enhancements. After wiring .bash_profile to source .bashrc, updates like PS1 changes show up both when reopening the terminal and when launching a subshell, without duplicating edits across two files.

Review Questions

  1. What happens to a PS1 prompt change made interactively when the terminal is closed and reopened, and why?
  2. On macOS, which startup file runs when opening a new terminal session, and which runs when starting a subshell with bash?
  3. What conditional sourcing pattern in .bash_profile ensures that .bashrc customizations apply to both login and non-login shells?

Key Points

  1. 1

    Interactive terminal tweaks (like setting PS1) apply only to the current shell session and reset on restart.

  2. 2

    Persistent behavior comes from editing dotfiles in the home directory, mainly .bash_profile and .bashrc.

  3. 3

    On macOS, opening a new terminal typically starts a login shell that runs .bash_profile, not .bashrc.

  4. 4

    Starting a subshell with bash triggers .bashrc, which is why .bashrc is the right place for non-login customizations.

  5. 5

    To avoid duplicating configuration, .bash_profile can conditionally source .bashrc when it exists.

  6. 6

    After sourcing is set up, prompt and other settings added to .bashrc apply consistently across new terminal sessions and subshells.

Highlights

Typing PS1=... customizes the prompt immediately, but the change disappears after reopening the terminal because startup files weren’t updated.
Echo statements in .bash_profile vs .bashrc make it clear which file runs for login shells versus subshells.
A small conditional in .bash_profile that sources .bashrc creates one unified customization point.
Once .bashrc is the single source of truth, PS1 and other settings persist across both login shells and subshells.

Topics

  • Bash Startup Files
  • .bash_profile vs .bashrc
  • Terminal Prompt Customization
  • Login Shells
  • Shell Initialization

Mentioned