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

NTFS 14.3.318 - $19.95
This latest version supports the new macOS 10.12 Sierra! NTFS breaks down the barriers between Windows and OS X. Paragon NTFS effectively solves the communication problems between the Mac system and... Read more
iFFmpeg 6.2.2 - Convert multimedia files...
iFFmpeg is a comprehensive media tool to convert movie, audio and media files between formats. The FFmpeg command line instructions can be very hard to master/understand, so iFFmpeg does all the hard... Read more
ForeverSave 2.1.6 - Universal auto-save...
ForeverSave auto-saves all documents you're working on while simultaneously doing backup versioning in the background. Lost data can be quickly restored at any time. Define your preferred time... Read more
BetterTouchTool 1.961 - Customize Multi-...
BetterTouchTool adds many new, fully customizable gestures to the Magic Mouse, Multi-Touch MacBook trackpad, and Magic Trackpad. These gestures are customizable: Magic Mouse: Pinch in / out (zoom... Read more
EtreCheck 3.1.4 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
Together 3.7 - Store and organize all of...
Together helps you organize your Mac, giving you the ability to store, edit and preview your files in a single clean, uncluttered interface. Features Smart storage. With simple drag-and-drop... Read more
Together 3.7 - Store and organize all of...
Together helps you organize your Mac, giving you the ability to store, edit and preview your files in a single clean, uncluttered interface. Features Smart storage. With simple drag-and-drop... Read more
EtreCheck 3.1.4 - For troubleshooting yo...
EtreCheck is an app that displays the important details of your system configuration and allow you to copy that information to the Clipboard. It is meant to be used with Apple Support Communities to... Read more
Postbox 5.0.9 - Powerful and flexible em...
Postbox is a new email application that helps you organize your work life and get stuff done. It has all the elegance and simplicity of Apple Mail, but with more power and flexibility to manage even... Read more
DiskCatalogMaker 6.5.16 - Catalog your d...
DiskCatalogMaker is a simple disk management tool which catalogs disks. Simple, light-weight, and fast. Finder-like intuitive look and feel. Super-fast search algorithm. Can compress catalog data... Read more

Latest Forum Discussions

See All

Clash of Clans is getting its own animat...
Riding on its unending wave of fame and success, Clash of Clans is getting an animated web series based on its Clash-A-Rama animated shorts.As opposed to the current shorts' 60 second run time, the new and improved Clash-A-Rama will be comprised of... | Read more »
Leaks hint at Pokémon GO and Starbucks C...
Leaked images from a hub for Starbucks employees suggests that a big Pokémon GO event with the coffee giant could begin this very week. The images appeared on Reddit and hint at some exciting new things to come for Niantic's smash hit game. | Read more »
Silent Depth Submarine Simulation (Game...
Silent Depth Submarine Simulation 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: | Read more »
Enneas Saga lets you lead your own demon...
Defend the land of Enneas Continent from the forces of evil in the new fantasy MMORPG from Lyto Mobi: Enneas Saga. Can’t wait? No problem. It’s available to download now on Android devices. | Read more »
Great zombie games in the spirit of Dead...
Dead Rising 4 arrives tomorrow, giving enthusiasts a fresh chance to take selfies with zombies and get up to other ridiculous end-of-the-world shenanigans. To really get into the spirit of things, we've gone and gathered the best zombie games that... | Read more »
Amateur Surgeon 4 Guide: Advanced tips a...
Amateur Surgeon 4 is still tackling the competition at the top of the App Store charts, so if you haven't tried it out yet, you should probably do that right away. If you've been at it for a while, though, perhaps you're ready to start expanding... | Read more »
Amateur Surgeon 4 Guide: Become the worl...
It's time to wield your trusty pizza cutter again, as Amateur Surgeon has returned with a whole fresh set of challenges (and some old, familiar ones, too). Starting anew isn't easy, especially when all you have at your disposal is a lighter, the... | Read more »
Le Parker: Sous Chef Extraordinaire (Ga...
Le Parker: Sous Chef Extraordinaire 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: | Read more »
Telltale Games really is working on a Gu...
Telltale Games' next episodic adventure is indeed Guardians of the Galaxy. A document tied to the voice actors strike suggested that the project was in the work, but now we have direct confirmation following an announcement at the Game Awards that... | Read more »
Amateur Surgeon returns to iOS and Andro...
Amateur Surgeon and its two sequels disappeared from the App Store some time and it was sad days for all. But now, just in time for the holidays, the Adult Swim favorite makes its joyous return in the shape of Amateur Surgeon 4, a remake with... | Read more »

Price Scanner via MacPrices.net

Back in stock! 13-inch 2.7GHz Retina MacBook...
Apple has Apple Certified Refurbished 2015 13″ 2.7GHz/128GB Retina MacBook Pros (MF839LL/A) available again for $1099 including free shipping. That’s $200 off MSRP, and it’s the lowest price... Read more
Slate Tablet Market Share to Fall Below 75% i...
After two years of decline, the tablet market is showing signs of new life as productivity trumps entertainment, and tablets become cost-effective computing devices for both entertainment and... Read more
Yostand Launches Indigogo campaign for iStand...
China-based startup Yostand (meaning ‘your stand’), has announced the launch of its Indigogo campaign for their newly awaited iStand7. This product is a one of a kind iPhone battery case that offers... Read more
Green App – Budget Forecasting Now Available...
Indianapolis, Indiana based CoopToons has announced the release of Green – Budget Forecasting 1.5, an update to their personal budgeting app developed exclusively for iOS devices. Green aims to be a... Read more
New 2016 13-inch 2.0GHz MacBook Pros in stock...
Overstock.com has the non-Touch Bar 13″ MacBook Pros in stock today for $150 off MSRP. Shipping is free: - 13″ 2.0GHz MacBook Pro Space Gray (MLL42LL/A): $1349.99 $150 off MSRP - 13″ 2.0GHz MacBook... Read more
15-inch 2.6GHz Silver Touch Bar MacBook Pro o...
Adorama has the new 2016 15″ 2.6GHz Silver Touch Bar MacBook Pro (MLW72LL/A) in stock and available for $2349 including free shipping. Adorama charges sales tax in NY & NJ only. Their price is $... Read more
13-inch MacBook Airs on sale for up to $180 o...
Overstock.com has 13″ MacBook Airs on sale for up to $180 off MSRP including free shipping: - 13″ 1.6GHz/128GB MacBook Air (MMGF2LL/A): $869.99 $130 off MSRP - 13″ 1.6GHz/256GB MacBook Air (sku... Read more
13-inch 2.5GHz MacBook Pro (Apple refurbished...
Apple has Certified Refurbished 13″ 2.5GHz MacBook Pros (MD101LL/A) available for $829, or $270 off original MSRP. Apple’s one-year warranty is standard, and shipping is free: - 13″ 2.5GHz MacBook... Read more
Monday roundup of Holiday Mac sales: Up to $3...
Take up to $300 off MSRP on the price of a new Apple Mac at B&H Photo today as part of their Holiday sale. Shipping is free, and B&H charges NY sales tax only. Touch Bar MacBook Pros are in... Read more
12-inch WiFi Apple iPad Pros on sale for up t...
B&H Photo has 12″ WiFi Apple iPad Pros on sale for up to $50 off MSRP, each including free shipping. B&H charges sales tax in NY only: - 12″ Space Gray 32GB WiFi iPad Pro: $749 $50 off MSRP... Read more

Jobs Board

*Apple* Retail - Multiple Positions - Apple,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
Lead *Apple* Solutions Consultant - Apple (...
# Lead Apple Solutions Consultant Job Number: 53586123 Pittsburgh, Pennsylvania, United States Posted: Nov. 28, 2016 Weekly Hours: 40.00 **Job Summary** The Lead ASC Read more
*Apple* Retail - Multiple Positions- Plano,...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions- Kansas...
Job Description:SalesSpecialist - Retail Customer Service and SalesTransform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
*Apple* Retail - Multiple Positions- Chicago...
Job Description: Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.