TweetFollow Us on Twitter

Mac in the Shell: Customizing the bash experience

Volume Number: 24 (2008)
Issue Number: 09
Column Tag: Shell

Mac in the Shell: Customizing the bash experience

Get comfortable in the bash shell and make the experience your own

by Edward Marczak

Introduction

I've written about bash for some time. Mac in the Shell has covered variables, loops and helpful OS X specific command-line utilities. We've even covered Terminal.app and ways to make it work the way you want. We haven't, though, covered customizing the bash shell itself. Not comprehensively, at any rate. There have been snippets here and there over time, but not in one Mac in the Shell article. It's time to rectify that. Follow along and get comfortable in the bash shell.

Back to the Beginning

For those of you that are new to this, why are "command-line people" so passionate about working the way they do? Why is the command-line interface (CLI) better then a graphical user interface (GUI)? Here's a quick recap:

Speed: even on the slowest Machines that can run Mac OS X, working in a shell will be practically as fast running on the fastest machine. The text-based interface is built for speed.

Nothing is hidden: Mac OS X's primary interface to the operating system, The Finder, hides certain aspects of the underlying system from the end user. I'd argue that this is perfectly the right decision for the bulk of end-users. However, you're a tech - you're reading MacTech, right? - and you need to know what's really going on.

Consistency: despite all of the changes that graphical interfaces have gone through over time, the text-based command line interface has really remained the same.

In short, there's room for both a GUI and a text-based shell, as they both have pros and cons. It's all about choosing the right tool for the job. Many people not familiar with a shell, though, tend to not really want to explore it as it is so foreign from the GUI. Just as many people are completely comfortable closing a window by pressing command-w, you can learn the keyboard shortcuts to maneuver about the command-line. It just takes practice. Let's wade in slowly.

Two things to note before going further: First, this article isn't meant to be a comprehensive guide to bash. Rather, its aim is to teach you things that will get you comfortable with the shell. Secondly, none of this is set in stone. I know many people whose primary environment is the command line. Each of them has preferred tricks and shell usage that suits them. Try each of the tips presented in this article and see which ones bind themselves to you.

Wading In

This article assumes two things: You're running Mac OS X v 10.5 "Leopard" as your operating system, and that bash is your primary shell. Everything described in this article will work just fine on 10.4 "Tiger," however, there may be slight discrepancies in terminal output. "Tiger" uses bash version 2.5 as its primary shell, and "Leopard" uses bash version 3.0, so, as you go deeper, Leopard has the more capable version of bash by default.

First thing's first: Open Terminal.app. Terminal.app is your gateway to the shell (in this case, bash). Terminal.app is located in Applications > Utilities. Open it now, and keep it in your Dock, because after this article, you're always going to use it! Once it's open, you'll see a small-ish white window, with text similar to the following:

Last login: Thu Jul  9 09:40:51 on console
jack-kerouac:~ marczak$ 

The bash shell prints the first line. You're told about the last time this account was logged in, and from where. "console" represents a login from Terminal.app (or other terminal program, such as iTerm or Terminator) via the GUI directly on the machine. A login via ssh would display the ip address of the machine that the remote session connected from. The following line is the prompt. As shown, the default prompt set by Apple lists the following attributes: hostname ("jack-kerouac"), the current directory ("~") and user name ("marczak"), all followed by a dollar sign ("$"). The dollar sign denotes the current effective user ID. Shortly, we'll talk about customizing the prompt. More importantly, though, don't look at this and be frightened off!

The tilde character represents your home directory. In the example prompt above, the current working directory is the home of user marczak. If you're rusty on basic shell commands, see the earlier Mac in the Shell column, "The Shell: What?," on-line at http://www.mactech.com/articles/mactech/Vol.21/21.03/TheShell/index.html. Just a quick example of how the prompt can be dynamic, change the current directory using the cd command:

jack-kerouac:~ marczak$ cd Library
jack-kerouac:~/Library marczak$

The prompt that you see is up to you. bash determines what to display by the contents of the variable $PS1. Let's see how the current prompt is defined:

$ echo $PS1
\h:\W \u\$ 

True to the description above, each backslash escaped substitution character displays a full value when actually at the prompt. Apple's default uses these characters:

\h - the current host name.

\W - the basename of the current working directory (with $HOME abbreviated as a tilde).

\u - the current username.

\$ - if the effective UID is 0, a #, otherwise a $.

(space) - you can't see it in print, but there is a space at the end of that sequence. This nicely separates the "$" or "#" character from the cursor and your typing.

Other characters in the string are taken literally, such as the colon (":") in "\h:\W \u\$". If PS1 is not set ("undefined"), bash uses "\s-\v\$ ". In other words:

\s - the basename of the current shell.

\v - the version of the current shell.

Which, on a 10.5.4 machine looks like this: "-bash-3.2$". See the "Prompting" section in the bash man page for a complete list of escape sequences. I've been setting my prompt like this for some time now:

"\u@\h\n[ \w ]$ "

This produces a two-line prompt, thanks to the newline character ("\n") embedded in the string. My prompt looks something like this:

marczak@lists
[ ~/download ]$

The user name ("marczak") and hostname ("lists") are prominently separated on one line, while the full current working directory ("~/download") precedes the input line. This prompt has been a huge help, as I have roughly 12 or more shells open at any given time, and tend to ssh into other systems often. This prompt is consistent across all machines I work with and allows me to quickly identify my UID, the system I'm on, and what directory I'm working in.

Editing Startup Files

If you've followed along up to this point in the article, you may have a prompt that you're very happy with. One that you want to show up each time you start up a shell. If that's the case, you need to add your definition of PS1 to a bash startup file. bash makes a distinction regarding a "login shell" and a "non-login shell." A login shell is created when starting up an initial shell. This occurs when starting Terminal.app, or, when accessing a remote machine via ssh. A non-login shell is a subshell. By default, bash runs the commands (or, "sources") in the following files every time a bash login-shell is created:

/etc/profile - the system-wide initialization file. All accounts logging in source this file.

One of: ~/.bash_profile, ~/.bash_login, and ~/.profile - whichever is found first is used.

A non-login shell skips all of the aforementioned files. It does have an initialization file, though: ~/.bashrc. This allows you to logically separate commands needed for login and non-login shells. If you peek in /etc/profile, you'll notice that Apple has included a command to also call /etc/bashrc for non-login shells. This is a slightly non-standard practice. The bash man page makes no reference to a system-wide /etc/bashrc file for non-login shells. Personally, I tend to not rely on non-standard setups like this. bash exists on other platforms and I like to keep practices that work across any system I'm using.

Consider this the "easy version" of bash initialization files. There are some other subtleties that you needn't be concerned with at this stage. For the curious, though, it's all in the bash man page.

To round this out, I keep the following line in my ~/.bash_profile file:

export PS1="\u@\h\n[ \w ]$ "

This way, I see the same prompt whenever I'm in a shell, even after a reboot.

Moving Around

Another thing that tends to frustrate people new to the shell is ease of moving around on the command line. In GUI apps, a point and click of the mouse sets the cursor (insert point) where you want it. This is almost possible in the shell, too. Apple's Terminal.app allows an option-click to place the cursor (this is an option in 10.4 that needs to be explicitly set). However, when at the keyboard, the less you reach for the mouse, the faster you can navigate.

By default, your shell is in emacs editing mode. Essentially, the keystrokes used to maneuver about the command-line mimic those used by emacs. Again, my aim here is to keep this tutorial simple and digestible. Starting out with these key commands will allow you greater flexibility initially, and you can then add more advanced commands into your repertoire.

Apple has mapped as many keys to sane equivalents as possible. Here's a list of the very obvious key commands that should put you right at ease:

left arrow, right arrow: position cursor on input line.

Delete, forward-delete: delete a character to the left, or beneath the cursor

As you type your input, use the left and right arrow keys to reposition the cursor one place to the left or right, respectively. The delete key behaves as expected; deleting the character to the left of the cursor and moving all of the text to the right of the cursor back one space. The forward delete also acts appropriately and deletes the character under the cursor while moving all text to the right of the cursor back one space.

While these key commands are certainly workable, they can get a little cumbersome when working with long lines of text.

ctrl-a, ctrl-e: move to beginning, end of input line, respectively.

option-f, option-b: move forward, backward by a word, respectively.

ctrl-k: kill from the cursor to the end of the input line.

option-d, ctrl-w: delete from the cursor to the next word or previous whitespace, respectively.

Try those, one at a time and get used to them. These commands come in most handy when working on a command-line that has a lot of text (a long line), but will work with any length line. Perhaps the easiest to get used to is ctrl-a and ctrl-e for jumping to the beginning of a line or to the end of the current line. If you use screen (see MacTech's article "Screen: Living in a Virtual World" at http://www.mactech.com/articles/mactech/Vol.21/21.09/Screen/index.html if you need an intro or refresher), you'll notice that ctrl-a interferes with the binding for screen commands. You can re-bind your screen key elsewhere, but as always, I like to keep apps using their default keys as much as possible. This simply adds an extra keystroke if you use screen; the command becomes ctrl-a, a (control-a, then 'a' on its own).

Shortening Commands

Another way to make your life on the command-line easier is to define aliases. Aliases are substitute commands that you define. Best way to demonstrate this is an example:

$ alias tsl="sudo tail -f /var/log/system.log"

This defines the alias "tsl" as "sudo tail -f /var/log/system.log". With this alias in place, simply typing "tsl" on the command line and pressing return will actually run "sudo tail -f /var/log/system.log". If there's some long, convoluted command that you find yourself typing often, consider making an alias to it to make your life a little easier, and lessen the number of keystrokes required to achieve your goal.

Like anything that you define in a single shell by typing it at the command-line, it's not going to persist into a new session. Once you start defining aliases, the ones that you want to be available to new shells need to be defined at shell login time (or, you can type them by hand each time...). Again, this is a perfect use for your shell initialization files. Anything placed in ~/.bash_profile will only affect your user account when logging in, or, you can place generally useful aliases in /etc/profile to affect all accounts that start a shell.

bash aliases are incredibly useful, but there are some quirks; nothing that you'll run into when just starting out, but things to be careful of later on. For example, aliases are evaluated after bash reads the current line completely. This causes a problem for an alias placed in the middle of a line that's expecting substitution:

$ files=$(ls -l /home/lists/) ; prf ; killall myproc

...where prf is an alias to some string. This will fail in some not so nice ways. For all intents and purposes, bash functions can do all that aliases can and more. Further, they behave as you'd expect any other command to behave.

Functions are defined with the function command. Here is a quick example script that uses a bash function that accepts a parameter:

Listing 1: list_for_local.sh

#!/bin/bash
function is_local_user() {
  dscl . -read /Users/${1} &> /dev/null
  if [ $? -ne 0 ]; then
    echo "Not a local user"
    exit 1
  else
    echo "User is local"
  fi
}
is_local_user ${USER}
ls -l

While this is a completely contrived example, it illustrates several points. First, functions are defined with the function keyword and curly braces block the definition itself. Secondly, it can span multiple lines and contain flow control (if/then or for loops), which aliases cannot. Finally, bash functions can be defined in bash initialization scripts and be available at the command prompt, just like an alias. If you wanted a quick command that did something particular based on some state - a file's status, the day of the week, and so on - the task could be defined as a bash function.

Of course, it could also be defined as a stand-alone script. Functions have an advantage, though. bash functions are evaluated in the current shell context. In other words, unlike a stand-alone script, bash does not fork off a new process to evaluate a function. That's nicer all around. Less processes running, and less context switching for the operating system. Bravo. The simple rule is this: if it's a short enough function that is used frequently, define it as a bash function in a bash initialization file.

Seeping In

It's probably about right to let all of that seep in. Work with all of the information presented here. Practice. A little at a time. I was hoping to get even a little further, but this is certainly enough to get started. Next month we'll go into more ways to make working in the shell easier.

The bottom line is this: no matter if you create applications in C, Python, Perl, Ruby or other language, you'll most likely need to interact with a shell and command-line applications in some manner. The shell is your interface to running these other utilities and programs you create. To run your Python application, you'll most likely interact with bash, as it's now the default shell. The more efficient you are with the shell, the more efficient you can be overall.

Media of the month: my one-month absence from writing Mac in the Shell came from having too many other priorities. One of which was as Executive Editor of this magazine to get the issue set and out the door! Another was my family. And another was writing one of the reference guides for Apple's ACSA Certification and course. In fact, three books and courses were created in parallel, each given topic perhaps nearer to your needs than the other. They're all deep pieces of work that each author worked incredibly hard on. I can't single one out, so, check out the title you wish. They're all part of the "Apple Training Series:"

Directory Services, by Arek Dreyer

Deployment, by Kevin White

Advanced System Administration, by Edward Marczak

...or check out all three! (Which you'll need to do to gain the 10.5 ACSA Certification). All have been written with the latest version of OS X - 10.5 at this writing.

Until next month, stay in practice!


Ed Marczak is the Executive Editor for MacTech Magazine, and has been lucky enough to have ridden the computing and technology wave from early on. From teletype computing to MVS to Netware to modern OS X, his interest was piqued. He has also been fortunate enough to come into contact with some of the best minds in the business. Ed spends his non-compute time with his wife and two daughters.

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Apple iTunes 12.1 - Manage your music, m...
Apple iTunes lets you organize and play digital music and video on your computer. It can automatically download new music, app, and book purchases across all your devices and computers. And it's a... Read more
LibreOffice 4.4.3 - Free, open-source of...
LibreOffice is an office suite (word processor, spreadsheet, presentations, drawing tool) compatible with other major office suites. The Document Foundation is coordinating development and... Read more
FoldersSynchronizer 4.2.1 - Synchronize...
FoldersSynchronizer is a popular and useful utility that synchronizes and backs-up files, folders, disks and boot disks. On each session you can apply special options like Timers, Multiple Folders,... Read more
Simon 4.0.2 - Monitor changes and crashe...
Simon monitors websites and alerts you of crashes and changes. Select pages to monitor, choose your alert options, and customize your settings. Simon does the rest. Keep a watchful eye on your... Read more
Cocktail 8.1.2 - General maintenance and...
Cocktail is a general purpose utility for OS X that lets you clean, repair and optimize your Mac. It is a powerful digital toolset that helps hundreds of thousands of Mac users around the world get... Read more
Cyberduck 4.6.4 - FTP and SFTP browser....
Cyberduck is a robust FTP/FTP-TLS/SFTP browser for the Mac whose lack of visual clutter and cleverly intuitive features make it easy to use. Support for external editors and system technologies such... Read more
Herald 5.0.2 - Notification plugin for M...
Note: Versions 2.1.3 (for OS X 10.7), 3.0.6 (for OS X 10.8), and 4.0.8 (for OS X 10.9) are no longer supported by the developer. Herald is a notification plugin for Mail.app, Apple's Mac OS X email... Read more
DEVONthink Pro 2.8.3 - Knowledge base, i...
Save 10% with our exclusive coupon code: MACUPDATE10 DEVONthink Pro is your essential assistant for today's world, where almost everything is digital. From shopping receipts to important research... Read more
Boom 2 1.0.1 - System-wide pro audio app...
Boom 2 is a system-wide volume booster and equalizer app that is designed especially for OS X 10.10 Yosemite. It comes with a smart interface, self-calibrates itself according to your Mac, offers... Read more
Apple Security Update 2015-001 - For OS...
Apple Security Update 2015-001 is recommended for all users and improves the security of OS X. For detailed information about the security content of this update, please visit: http://support.apple.... Read more

Storm the Halls of Echo Base in First St...
Storm the Halls of Echo Base in First Star Wars: Galactic Defense Event Posted by Jessica Fisher on January 30th, 2015 [ permalink ] Universal App - Designed for iPhone and iPad | Read more »
Contradiction Review
Contradiction Review By Tre Lawrence on January 30th, 2015 Our Rating: :: SPOT THE LIEiPad Only App - Designed for the iPad Contradiction is a live action point and click adventure that’s pretty engaging.   Developer: Tim Follin... | Read more »
Unlock Sunshine Girl in Ironkill with th...
Unlock Sunshine Girl in Ironkill with this special 148Apps code Posted by Rob Rich on January 29th, 2015 [ permalink ] Robo-fighter Ironkill has been out on iOS a | Read more »
Crossroad Zombies Review
Crossroad Zombies Review By Jordan Minor on January 29th, 2015 Our Rating: :: CROSSWALKING DEADiPad Only App - Designed for the iPad Crossroad Zombies is a rough draft of a cool genre mash-up.   | Read more »
Blood Brothers 2 – Tips, Cheats, and Str...
War is hell: Is it the kind of hell you want to check out? Read our Blood Brothers 2 review to find out! Blood Brothers 2, DeNA’s follow-up to the original Blood Brothers, is an intriguing card collecting / role-playing / strategy hybrid. There’s... | Read more »
Blood Brothers 2 Review
Blood Brothers 2 Review By Nadia Oxford on January 29th, 2015 Our Rating: :: AN AGGRAVATING RELATIVEUniversal App - Designed for iPhone and iPad Blood Brothers 2 is built on a simple, solid foundation, but its free-to-play system... | Read more »
I AM BREAD, the Toast of the Town, is Ro...
Have you ever dreamt of being deliciously gluten-y? Do you feel passionate about Rye and Wheat? The guys at Bossa Studios do and that is why they are bringing I AM BREAD to iOS soon. The loafy app will feature all the new content that is being... | Read more »
Fahrenheit: Indigo Prophecy Remastered R...
Fahrenheit: Indigo Prophecy Remastered Review By Jennifer Allen on January 29th, 2015 Our Rating: Universal App - Designed for iPhone and iPad 10 years after its initial release and Fahrenheit: Indigo Prophecy still feels like a... | Read more »
Evolve: Hunters Quest is a Match-3 That...
Evolve: Hunters Quest is a Match-3 That Has You Hunting Up Some Big Game. Posted by Jessica Fisher on January 29th, 2015 [ permalink ] | Read more »
Destructamundo Review
Destructamundo Review By Jordan Minor on January 29th, 2015 Our Rating: :: WRECKING CREWUniversal App - Designed for iPhone and iPad Destructamundo blows up real good.   | Read more »

Price Scanner via MacPrices.net

Back in stock: Refurbished iPod nanos for $99...
The Apple Store has Apple Certified Refurbished 16GB iPod nanos available for $99 including free shipping and Apple’s standard one-year warranty. That’s $50 off the cost of new nanos. Most colors are... Read more
New Good Management Suite Simplifies Enterpri...
Good Technology has announced the availability of the Good Management Suite, a comprehensive cross-platform solution for organizations getting started with mobile business initiatives. Built on the... Read more
15-inch 2.0GHz Retina MacBook Pro (refurbishe...
The Apple Store has Apple Certified Refurbished previous-generation 15″ 2.0GHz Retina MacBook Pros available for $1489 including free shipping plus Apple’s standard one-year warranty. Their price is... Read more
15-inch 2.5GHz Retina MacBook Pro on sale for...
Amazon has the 15″ 2.5GHz Retina MacBook Pro on sale for $2319.99 including free shipping. Their price is $180 off MSRP, and it’s the lowest price available for this model from any reseller. Read more
iPad Turns Five – The ”Book Mystique
Five years ago this week, the late Steve Jobs took the stage at an Apple special press event to unveil the first Apple iPad — a slab-shaped, hand-holdable device that was to shake the personal... Read more
Sale! 15-inch Retina MacBook Pros for up to $...
B&H Photo has the new 2014 15″ Retina MacBook Pros on sale for $150 off MSRP for a limited time. Shipping is free, and B&H charges NY sales tax only: - 15″ 2.2GHz Retina MacBook Pro: $1889.99... Read more
Apple refurbished Mac minis for up to $150 of...
The Apple Store has restocked Apple Certified Refurbished 2014 Mac minis, with models available starting at $419. Apple’s one-year warranty is included with each mini, and shipping is free: - 1.4GHz... Read more
Apple Releases New Tranche Of OS Updates For...
Apple has released incremental bugfix and security updates for its most recent Mac and iOS versions. OS X Yosemite 10.10.2 Update Apple says this update includes the following improvements: Resolves... Read more
Samsung To Be Main Supplier Of A9 Chips For i...
Korea’s Maeil Business Newspaper reports that Samsung has beat out its chipmaking rivals, Taiwan’s Qualcomm and TSMC, as supplier of chipsets for the next generations of both its own Galaxy S6 and... Read more
Save up to $340 on iMacs with Apple Certified...
The Apple Store has Apple Certified Refurbished iMacs available for up to $340 off the cost of new models. Apple’s one-year warranty is standard, and shipping is free. These are the best prices on... Read more

Jobs Board

At-Home Chat Specialist- *Apple* Online Stor...
**Job Summary** At Apple , we believe in hard work, a fun environment, and the kind of creativity and innovation that only comes about when talented people from diverse Read more
SW QA Engineer - *Apple* TV - Apple (United...
**Job Summary** The Apple TV team is looking for experienced Quality Assurance Engineers with a passion for delivering first in class home entertainment solutions. **Key Read more
*Apple* Retail - Multiple Positions(US) - Ap...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you re also the Read more
*Apple* Systems Engineer - Pre Sales, Educat...
…is responsible for proactively providing technical expertise to drive sales of Apple solutions into assigned accounts. The SE architects, validates, and assists in Read more
*Apple* Solutions Consultant - Retail Sales...
As an ambassador of the Apple brand, the ASC is accountable for driving sales performance by: Connecting with customers. Discovering customers' needs and values. Showing Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.