Braving Bash, Part 1

In which I face my fears and finally decide to learn what’s happening in ~/.bash_profile and ~/.bashrc.

At some point in early grade school, after I had exhausted my Jetpack attention span and my ideas for Hypercard-based animated art, I decided I would explore all of the settings I could find on my parents’ Macintosh SE. I was feeling very knowledgable, right up until the moment I stumbled onto the Sad Mac:

Sad Mac

Cue panic.

My dad assures me “the sad Mac was way more common in those days—the MacOS was easier to break,” but even so: since then, I’ve been a bit squeamish about messing around under the hood of my computers.

And then I decided to learn how to code, which—once you make it past online tutorials like Code Academy and Free Code Camp—almost always starts, in my experience, with being told to run a bunch of commands in Terminal and/or paste a bunch of code into your ~/.bash_profile and/or ~/.bashrc files. If you’re lucky, these instructions come with explanations, but often, you have to take it on faith.

I’ve done my best to ignore the creeping feelings of unease and the shades of decades-old Sad Mac panic for several years, dutifully following the instructions and watching these files grow more and more bloated.

When I started at GA, we were given around 20 lines of code to paste into the two files. The next time I opened up Terminal, I saw this:

Last login: Tue Sep 27 11:39:11 on ttys003
You have new mail.
[1;90m
—————————-
Loaded ~/.bashrcTo edit run $ bashedit
To refresh run $ bashrefresh

You are: Rebekah
You’re in: /Users/Rebekah

All aliases…$ alias
—————————-
[1;90m
—————————-
Loaded ~/.bashrc

To edit run $ bashedit
To refresh run $ bashrefresh

You are: Rebekah
You’re in: /Users/Rebekah

All aliases…$ alias
—————————-
~ $

That’s not a copy and paste error: I was getting TWO COPIES of a welcome message I didn’t remember setting but had mostly ignored for several years because everything else seemed to function well enough.

Two copies. Of a message I can’t remember asking for. That starts with 1;90m, which, for all I knew, could be CRITICALLY IMPORTANT SUPER SEKRIT BASH CODE or, you know, a typo.

That's enough!

It was time to fix this.

Step One: Actually look at the code

My approach to all things bash-related for as long as I can remember has been to open up the file(s) using nano, paste in whatever I’m told to paste in wherever I’m told to paste it (usually at the very top or very bottom), save, and close out as quickly as possibly to avoid breaking things.

Pro tip: this is not a good way to understand how things work.

This time, I copied the contents of each file to a separate file so I could “safely” open them up, annotate them, and experiment without—I hoped—bricking my laptop.*

Here’s my ~/.bashrc:

And here’s my ~/.bash_profile:

WAT

Step Two: Ask questions

Now that I had code to look at, I could start googling.

First up: what’s the difference between these two files? Stack Exchange says:

.bash_profile is executed for login shells, while .bashrc is executed for interactive non-login shells.

When you login (type username and password) via console, either sitting at the machine, or remotely via ssh: .bash_profile is executed to configure your shell before the initial command prompt.

But, if you’ve already logged into your machine and open a new terminal window (xterm) then .bashrc is executed before the window command prompt. .bashrc is also run when you start a new bash instance by typing /bin/bash in a terminal.

Cool. I log into my machine every time I restart it or wake it up, and I started this whole journey because of what I was seeing when I opened a new Terminal window. Sounds like I should be looking at .bashrc then. Oh, but wait—there’s more:

if you add the following to your .bash_profile, you can then move everything into your .bashrc file so as to consolidate everything into one place instead of two:

if [ -f $HOME/.bashrc ]; then
  source $HOME/.bashrc
fi

Interesting. I have something pretty similar in lines 6-8 of my .bash_profile:

It’s the same code, minus the $HOME part of the file path. Some more googling leads me to The Linux Documentation Project’s Bash Guide for Beginners, which tells me that -f will be “True if FILE exists and is a regular file.” source means run the code in the file.

To sum up: if a .bashrc file exists in the $HOME directory (in my own .bash_profile, this is written as ~/.bashrc, which means the same thing), then run all of the code it contains.

Okay! Now we’re getting somewhere, sort of: I know that I have two files, and I know that, given how they’re currently set up, they’re both executing when I open a window in Terminal.

Next up

In Part 2: what is all that executable code doing?

Notes and questions

* Is this a thing that’s even possible to do from ~/.bash_profile? It’s been a fear of mine for years. If you know the answer (or can share a good resource), please let me know.

Resources

The Linux Documentation Project’s Bash Guide for Beginners, by Machtelt Garrels