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

  • Hal Roberts

    Yes, you can brick your computer by putting the wrong thing in your
    .bashrc / .bash_profile / .profile files! Those files are just bash
    scripts.

    Bash is both a shell (a program that interactively accepts commands
    and returns results) and a programming language (to enable more
    powerful and flexible interaction with commands). So if you added,
    for instance, a command to delete all of your files, the next time you
    logged into your shell, bash would run that command and delete all of
    your files.

    FWIW, your bash init files are all messed up because folks have
    behaved badly in having you add a bunch of useless confusing crud to
    them. It’s bad practice to have folks add stuff to their bash init
    files precisely for this reason — the files end up cluttered with
    special case code that is often more hurtful than helpful and that
    will almost certainly conflict with other such edits.

    I’m happy to annotate what’s in there for you and / or suggest an
    edited version without all of the completely useless noise. Or not if
    you want to struggle through to learn it yourself.

    I highly recommend investing the time reading something like the below
    to get a good grounding in the world of the command line:

    http://shop.oreilly.com/product/9780596009656.do

    I know that it is daunting to be recommended a 350 page book to fix a
    simple init file, but knowing how to navigate bash and the unix
    command line will change your life in a good way. Sadly, bash is not
    easy to learn, even though it makes the computer much easier (and more
    elegant and more fun) to use once you have learned it. For a longer
    argument:

    http://www.cryptonomicon.com/beginning.html