macdevcenter.com
oreilly.comSafari Books Online.Conferences.

advertisement

AddThis Social Bookmark Button

bash on Mac OS X

by David Miller
02/24/2004

If you're curious about this article, chances are you've played around with the Terminal in OS X and have become accustomed to the command-line interface, or you've worked with files through commands that you type rather than menus and icons that you click. If that's not the case, then you should first read Chris Stone's series of articles, titled "Learning the Mac OS X Terminal", and "Learning the Terminal in Jaguar."

In the switch from Jaguar to Panther, one of the footnotes that has occasionally been mentioned is the switch from tcsh to bash as the default shell in Mac OS X. Those who upgraded from Jaguar to Panther will still be using tcsh when they log in to Panther for the first time since your existing preferences will be respected; only new accounts that are created from within Panther will use bash by default. Most casual Terminal users won't notice the difference between the two, as the usual suspects will still work exactly as they did before:

  • cd will still move you to a different directory,
  • ls will still list the contents of a directory,
  • rm will still delete files,
  • and you can still use the arrows to scroll through your history of commands.

But those who have played around with aliases, environment variables, or other parts of tcsh will find that their lovingly crafted environment is nonexistent when using bash. This article will help those who have played around with tcsh in Jaguar make the transition to bash in Panther (and, in doing so, will quite possibly contain more screen captures of the Terminal than any Mac DevCenter article before it).

Unix 101: What Is a Shell?

Related Reading

Learning the bash Shell
By Cameron Newham, Bill Rosenblatt

If you've reached this point, chances are that you know that the shell acts as the glue between you and the big, hairy beast that hides in the deepest, darkest recesses of your computer. This beast, known as the kernel, happens to be at the top of your computer's food chain; it governs the resources (memory, processor, and disk) that each process receives, and ensures that everything is running as it should.

So you can imagine what would happen if a kernel doesn't behave properly: applications start crashing, the dreaded pinwheel appears, and the computer generally starts doing weird things. Chances are you've stumbled across this situation before, even if you didn't know it at the time: Windows users are familiar with the "blue screen of death," while those of us who have used one of the various incarnations of Mac OS X have probably come across a few kernel panics here and there.

What you may not have known is that you aren't restricted to which shell you use to keep control of the beast; several shells have been created in the 40-some odd years that Unix has been around. They all do the same job, but each is unique in the features it provides and the syntax it supports.

A Brief History of Shells

The first shell (sh), dubbed the Bourne Shell in honour of its creator Stephen Bourne, was developed at AT&T Bell Labs to accompany the first release of the Unix operating system. Since it was the first shell developed, the Bourne Shell serves as the foundation for all shells that have been created since.

The Bourne Again Shell (bash), whose name is a pun on its ancestor, is fully compatible with the Bourne Shell and includes extra features such as job control, command-line editing, and increased scripting support; consider it to be the Bourne Shell's official replacement. Developed and maintained by the Free Software Foundation, bash's source is freely available, which allows you to compile it on just about any flavour of Unix.

So if you make the jump to Linux or *BSD chances are bash will be waiting there to accept your command when you open up Konsole or Gnome Terminal for the first time.

I Can't Tell the Difference. Can You Tell the Difference?

Windowing systems, such as Aqua, KDE, and Gnome all have menus, icons, windows, and a cursor to dictate your actions to the underbelly of your computer. But each has its own unique quirks (for better or for worse) when compared to the others, in ways that are more than just superficial. For example, Aqua's sheets provide an alternative method of implementing dialog boxes for multiple document applications such as web browsers and word processors, since the user is still able to use another window while the dialog is present.

In much the same way, shells each have their own unique quirks that differentiate themselves, yet each accomplishes the same function: to relay your commands to the big hairy beast in your computer, and in turn, to ferry the results back to you. This is why most of the commands included in your ~/.tcshrc now fail when you try to execute them in bash, since bash uses a different syntax for many of its equivalent commands.

The Kitchen Sink

In addition to the other Unix components of the operating system, Panther installs five shells, all of which are stored in the same location as most other executable programs on Mac OS X, /bin:

Panther's shells: sh, bash, csh, tcsh, and zsh
Figure 1: The shells included with Panther are sh, bash, csh, tcsh, zsh.

Judging by the sizes of the files, it would appear as though bash and sh are in fact identical, while tcsh and csh are identical; this meshes with the introduction to the different shells discussed earlier, since bash is backwards compatible with sh (as is tcsh with csh).

It is important to note that you are by no means limited to using the shells in the above list; several other shells, such as the Korn shell (ksh) can be downloaded and compiled on Mac OS X (or any other Unix system). However, the vast majority of Panther users will likely find the selection more than enough for their needs; if your shell of choice isn't included, chances are you've already downloaded the tarball and compiled it.

Making the Switch

Mac OS X provides several ways to change your default login shell. And given OS X's split personality of Unix workstation and friendly desktop computer, it should be no surprise that one method is accomplished through the shell itself, while the other is accessible to anyone with a (one button) mouse.

Via the Interface

Oddly enough, it's possible to try to change your default login shell without actually knowing what a shell is. Whether or not that's a good thing is up in the air, but to do it just open Terminal's preferences window and enter the path of the shell in the "Execute this command" text field, as shown below:

Terminal Preferences
Figure 2: Using Terminal's preferences window to switch to bash.

Then quit Terminal, and restart it to allow the new settings to take effect.

Via the Shell

The above method of changing your shell is a convenience provided by Apple. But, like many configuration options that apply to the Unix underbelly of Mac OS X, it is merely a graphical front-end to a Unix command that can be invoked in Terminal.

Back in the days before windows and mice, everything had to be done through the command-line -- scary, isn't it? On most Unix systems, changing your shell to bash would be done through the command chsh bash. However, Apple has slightly modified the chsh command in OS X (more specifically, Darwin) so that we must now use chsh -s bash to accomplish this task on our candy-coated machines:

The results of attempting to change your shell, both successful and unsuccessful.
Figure 3: The results of attempting to change your shell, both successfully and unsuccessfully.

Again, restart Terminal to ensure that your changes have taken effect.

Working with bash

Whether you've gone ahead and changed your shell or Panther set it up automatically, you are now working with bash; you can even double-check by checking the results of the command echo $SHELL in Terminal.

Because of the size and complexity of bash, we won't be able to cover all of its features here. Instead, we'll take a look at the most common stumbling blocks that people find when moving from tcsh to bash and focus on those. So let's get started.

Customizing Your Environment

Every time you log in to your computer, bash will look for initialization files that are used to customize your environment, in exactly the same way that tcsh and the other shells do. Thus, instead of executing the same commands every time you log in, you can place these commands in your initialization file so that bash will do the grunt work for you. bash looks for these files in a few different locations, with each having its own distinct purpose:

File Description
/etc/profile system-wide configuration file for the bash and sh shells
~/.profile executed every time a new shell is created, such as when you open a new Terminal window
~/.bash_logout executed when you log out from a shell

Thus, the commands that you wish to invoke every time you open a Terminal should be placed in your profile, located at ~/.profile (you'll have to create it if it doesn't exist). If you wish to have this command executed for every account on your computer that uses bash, place it in the /etc/profile file instead.

A sample initialization file follows:


# shell variables
PS1="\n$PS1 "
PS2=": "

# environment variables
export CVSROOT=/usr/local/cvsroot
export CVS_RSH=/usr/bin/ssh
export JAVA_HOME=/Library/Java/Home
export ANT_HOME=/usr/local/ant
export CLASSPATH=/Users/dave/FVL/xerces.jar

# the path is initially set to "/bin:/sbin:/usr/bin:/usr/sbin"
export PATH=$PATH:/usr/local/bin:/usr/local/mysql/bin

# aliases
alias l="ls -l"
alias ll="ls -al"
alias mckoi="java com.mckoi.runtime.McKoiDBMain"

If you've played around with shell variables and aliases in tcsh, then the commands shown above should look pretty familiar. You'll need to "refresh" your profile after every edit so that the latest changes take effect (think of refreshing your web browser to get the latest copy of a web page). This can be done with the command source filename; so in the case of your log out script, the command source ~/.bash_logout would do the trick.

Shell Variables

A variable, when speaking of programming languages, serves as a placeholder for information that will be retrieved at some point later in the program, such as a number, string, or date. When applied to shells (which actually are programming languages), variables may store your current directory, your prompt string, or any other piece of information required by the tools and programs you use. bash has two types of variables: "regular" variables and environment variables.

Pages: 1, 2

Next Pagearrow