General Computing
linux bash terminal shell bashrc
Updated Fri, 20 May 2022 01:12:31 GMT

Why do people source bash_profile from bashrc instead of the other way round?

It sounds like most terminal emulators don't run local sessions as login by default, so they'll load bashrc rather than bash_profile. So why do most people put everything in bash_profile and have bashrc source it rather than the other way around? By "most people" I mean most people I've seen so far. Maybe it's not as widespread as I think.

Instead of putting our configuration there and having bashrc source bash_profile, wouldn't it make more sense and be more consistent with the linux community to put everything in bashrc and have bash_profile source that?

I've heard good things about iTerm2, and it sounds like that and just about every other terminal emulator out there (other than the default OSX Terminal) would end up loading bashrc when I'm running locally. Not that it matters, as long as one sources the other, but I'm confused why preferring bash_profile is the standard?

Minor side-note: I was mistaken about iTerm2. It defaults to running login sessions, just like, though both emulators appear to have an option that lets you alter that.


People source bash_profile from bashrc instead of the other way around due to local convention.

All the opinion that I've read about how one configures their startup files in bash is primarily based on local convention. The local convention usually doesn't mention the big picture in that it doesn't talk much about the non-login, non-interactive case. The funny thing is, and I've looked, but I rarely see anyone mention cron in all their talk about why to put variables in one startup file versus the other. In fact, I've not heard one comment say: "/bin/sh is there for a reason. Bash emulates the original Bourne shell, /bin/sh, when invoked as such." For one thing, and I digress slightly, this case is important to people who work with the shell not only interactively, but who provide non-interactive, non-login (unattended or background) cron scripts that need minimal shell processing i.e. background processing doesn't require the niceties of colored prompts, command history and substitution, a properly defined $TERM variable, etc.

Further and with respect to cron, what I usually see is people creating minimal search paths or calling programs fully qualified, and not knowing how to deal with output not connected to a terminal (i.e. the non-interactive, non-login bash or sh case) when working with their cron scripts. This is usually because a good understanding of the shell startup sequence isn't fully understood, which leads to a user implementing their own startup files in a manner that is inconsistent or incoherent with the conventions already established in the local /etc startup files.

Elaborating, the setup done by local convention is laid out in that particular installation and shell's /etc files. If one examines any UNIX installation's /etc files, which are invoked as part of a typical bash startup sequence, then one should create their own start-up in a manner that is complimentary to the convention established in those /etc startup files.

The Linux Documentation Project states:

/etc/skel/ The default files for each new user are stored in this directory. Each time a new user is added, these skeleton files are copied into their home directory. An average system would have: .alias, .bash_profile, .bashrc and .cshrc files. Other files are left up to the system administrator.

Though the bash manual doesn't mention these files that are commonly found in the /etc/skel directory explicitly, from what I recall, SunOS, Solaris, RedHat, Ubuntu, HP-UX, umips, & Ultrix have /etc/skel files to pattern a user's shell startup files after. OSX clearly does not - I'm using OSX 10.9.1 right now. Unfortunately, OSX doesn't give you much to go on in terms of how things should be setup in terms of convention, but since OSX is a BSD derivative, I simply used another BSD derivative, and patterned my own bash startup sequence after that, adjusting it to fit into the local conventions used in the OSX 10.9.1 /etc startup files.

An important point that was mentioned in a parallel comment is that for OSX, the convention is to start every new Terminal as an interactive login shell. This is indeed the default in OSX. There is no problem with this convention as long as the users of an installation are consistent. The default behavior for the Terminal on OSX may be changed to conform with other UNIX distribution's shell startup conventions by making the following change to the Terminal's preferences, in particular, change the setting, Shells open with: to issue the /usr/bin/login -f -l whmcclos bash -i command:

enter image description here

With all that as a background or introduction, I will segue into my best advice, for what it's worth.

My best advice:

Examine the files the admins of your UNIX distribution have put in place. Start with the following locations, if they exist. Don't forget to use the ls -a command, because some of the files begin with a dot. See how these files are used during startup, and see how your own startup files interact with them:


Look in the bash manual for the invocation and startup sequence. It is all laid out very well.

With all that as a caveat - here is how I did things on my OSX 10.9.1 installation - Other UNIX distributions WILL be different, but what is presented below should work on most if not all UNIX distributions, but use those other UNIX distributions' convention as a guide to tailor the below for your own purposes:


# ~/.profile: executed by the command interpreter for login shells.
# This file is not read by bash(1), if ~/.bash_profile or ~/.bash_login
# exists.  Note, however, that we will have a ~/.bash_profile and it
# will simply source this file as a matter of course.
# See /usr/share/doc/bash/examples/startup-files for examples.
# The files are located in the bash-doc package.
# From here on out, I basically set up my PATH, LD_LIBRARY_PATH, and anything else I'd like
# global to running programs and how those programs find their libraries.  This is shared by
# `cron`, so we really don't want interactive stuff, here.  Also, I setup my environments
# for brew, macports, and fink here, essentially with setting PATH, and invocation of those
# package initialization file as in:
# Brew and locally compiled stuff:
export PATH=/usr/local/bin:$PATH
export PATH=/usr/local/sbin:$PATH
# The following line puts gnu utilities without the prefix "g" in the path
# i.e. tar/gtar:
export PATH=$PATH:/usr/local/Cellar/coreutils/8.21/libexec/gnubin
# MacPorts shoves stuff in /opt, so to get at that stuff...
export PATH=/opt/local/bin:$PATH
export PATH=/opt/local/sbin:$PATH
# Set up for using Fink, which lives in /sw:
[ -e /sw/bin/ ] && . /sw/bin/
# My stuff:
export PATH=~/perl:$PATH
export PATH=~/bin:$PATH
export PATH=.:$PATH


# ~/.bashrc: executed by bash(1) for non-login shells.
# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc)
# for examples
# If not running interactively, don't do anything
[ -z "$PS1" ] && return
# From here on out, I put in things that are meaningful to interactive shells, like aliases,
# `shopt` invocations, HISTORY control, terminal characteristics, PROMPT, etc.


# ~/.bash_profile: executed by the command interpreter for login shells.
# Because of this file's existence, neither ~/.bash_login nor ~/.profile
# will be sourced.
# See /usr/share/doc/bash/examples/startup-files for examples.
# The files are located in the bash-doc package.
# Because ~/.profile isn't invoked if this files exists,
# we must source ~/.profile to get its settings:
if [ -r ~/.profile ]; then . ~/.profile; fi
# The following sources ~/.bashrc in the interactive login case,
# because .bashrc isn't sourced for interactive login shells:
case "$-" in *i*) if [ -r ~/.bashrc ]; then . ~/.bashrc; fi;; esac
# I'm still trying to wrap my head about what to put here.  A suggestion
# would be to put all the `bash` prompt coloring sequence functions as
# described on

So that's my two cents. Keep in mind that my examples have tried to show the control path through the startup files and avoid what any particular site's conventions may impose.

Comments (5)

  • +0 – Of late, Apple has included messages in the cron man page saying that it is still supported, but Apple claims that the launch service is more flexible, I'm not abandoning cron background process, but I know that the system administrators really dislike leaving me with a control-thread when I'm not technically logged in. Get a grip. Speaking of control threads to get in, somewhere around Yosemite, the ssh port 22 has been subsumed by the launch service, and the launch service intercepts the ssh attempt, and then routes that to port 22! — Jul 17, 2016 at 13:38  
  • +0 – The reason I bring up the re-routine of port 22 for ssh is that sooner or later, your gonna get into rsa PGP keys and the like, and to make this comment apropos, it is essential your .bashrc and .bash_profile are setup properly, or ssh type ghost login attempts for simple service, especially with PGP encryption enabled, will FAIL miserably! So make sure you get your .bashrc and .bash_profile, etc are in place before dabbling in PGP and ssh. if a simple "ssh me@myIP ls" failed, investigate making sure you have the above .bash_profile, etc. files correct and in place, or copied from someone — Jul 17, 2016 at 13:48  
  • +0 – I only make the last comment in that I setup 3 ssh accounts over the last 3 months, and each time, I did all the right steps, but setup the startup shell scripts, and then spent hours trying to figure out why I had to invoke "ls" as "/bin/ls", and nothing else worked very well. Each of 3 times, I forgot to give the new user a copy of my shell startup files. And, once I did, each time, all their problems went away. So? There you go. A kind of background processing - ssh'd connections for services. — Jul 17, 2016 at 13:53  
  • +0 – Great answer! One thing, I see you mention a file at /etc/bashrc in addition to /etc/nash.bashrc. I was about to remove that assuming it was a mistake but I thought I'd ask. Are there any systems that ship with an /etc/bashrc file? I haven't seen one in the Linux world. — Nov 25, 2017 at 14:35  
  • +0 – Mac OS X 10.13.1, which I installed recently, has a pre-installed /etc/bashrc file. — Nov 28, 2017 at 04:41  

External Links

External links referenced by this document: