Customizing Your Shell Environment

The Unix shell reads a number of configuration files when it starts up. These configuration files are really shell programs, so they are extraordinarily powerful. Shell programming is beyond the scope of this book. For more detail, see Cameron Newham and Bill Rosenblatts’ book Learning the bash Shell (O’Reilly) or Dave Taylors’ Wicked Cool Shell Scripts (NoStarch). Because Unix is a multiuser system, there are two possible locations for the configuration files: one applies to all users of the system and another to each individual user.

The system-wide setup files that are read by bash, the default shell for Mac OS X, are found in /etc (profile and bashrc). You only have permission to change these system-wide files if you use sudo (see Section 3.3 in Chapter 3). However, you can create another file called .profile in your home directory that will add additional commands to be executed whenever you start a new Terminal window. (If you configure Terminal to use another shell, such as the Bourne shell, the C shell, or the Z shell, you’ll need to set up different configuration files. See the manpage for the appropriate shell for details.)

The system-wide setup files are read first, then the user-specific ones, so commands in your .profile file can override those in the system-wide files. The system-wide profile and bashrc files are succinct:

$ cat /etc/profile
# System-wide .profile for sh(1)

PATH="/bin:/sbin:/usr/bin:/usr/sbin"
export PATH

[ -r /etc/bashrc ] && source /etc/bashrc
$ cat /etc/bashrc
# System-wide .bashrc file for interactive bash(1) shells.
PS1='\h:\w \u\$ '
$

If you want to change the PATH for all users, perhaps to add /Developer/Tools (see Chapter 4 for details on what you can find in that directory), modify the /etc/profile contents thusly:

PATH="/bin:/sbin:/usr/bin:/usr/sbin:/Developer/Tools"

The .profile file can contain any shell command that you want to run automatically whenever you create a new Terminal. Some typical examples include changing the shell prompt, setting environment variables (values that control the operation of other Unix utilities), setting aliases, or adding to the search path (where the shell searches for programs to be run). A .profile file could look like this:

export PS1="\w (\!) : "
export LESS="eMq"
alias desktop="cd ~/Desktop"
date

This sample .profile file issues the following commands:

  • The line that changes the value of PS1 tells the shell to use a different prompt than the standard one. We’ll explain the details of prompt setting in Section 1.3.1 later in this chapter.

  • The line with export LESS sets a shell variable that the less program recognizes to change its default behavior. In this case, it’s identical to typing in less -eMq each time you use the command. Not all commands recognize environment variables, but for those that do, this saves you the trouble of typing the options on every less command line.

  • The line that begins with alias defines a new, custom command that your shell will recognize just as if it were a built-in Unix command. Aliases are a great way to save shorthand names for long, complicated Unix command lines, or even to fix common mistakes you might make when typing command lines. This particular alias creates a command for going right to the Desktop directory. We give a brief tutorial on creating aliases later in this chapter in Section 1.3.2.

  • The date line simply runs the date command to print the time and date when you open a new Terminal window. You probably don’t want to do this, but we want you to understand that you can put in any command that you could type at the shell prompt and have it automatically executed whenever a new shell starts up.

By default, the .profile file doesn’t exist in your home directory, and only the system-wide configuration files are read each time a Terminal window is opened. But if you create the file in your home directory, it will be read and its contents executed the next time you start a shell. You can create or change these files with a text editor, such as vi (see Section 4.3.2 in Chapter 4). Don’t use a word processor that breaks long lines or puts special nontext codes into the file. Any changes you make to these files will take effect when you open a new Terminal window. Unfortunately, it’s not always easy to know which shell setup file you should change. And an editing mistake in your shell setup file can interfere with the normal startup of the Terminal window. We suggest that beginners get help from experienced users, and don’t make changes to these files at all if you’re about to do some critical work with your account, unless there’s some reason you have to make the changes immediately.

You can execute any customization command we discuss here from the command line as well. In this case, the changes are in effect only until you close that window or quit Terminal.

For example, to change the default options for less so it will clear the Terminal window before it shows each new page of text, you could add the -c option to the LESS environment variable. The command would look something like this:

$ export LESS='eMqc'

(If you don’t want some of the less options we’ve shown, you could leave those letters out.)

Unix has many other configuration commands to learn about; the sources listed in Chapter 10 can help you identify which modifications you can make and how they can help you produce an optimal computing environment for yourself.

Just as you can execute the setup commands from the command line, the converse is true: any command that you can execute from the command line can be executed automatically when you log in by placing it in your setup file. (Running interactive commands such as vi or ftp from your setup file isn’t a good idea, though.)

Changing Your Prompt

The easiest customization you can perform is to change your prompt. By default, bash on Mac OS X has a shell prompt made up of your computer hostname, your current working directory, your account name, and a dollar sign (for example: Dave-Taylors-Computer:~ taylor$). If you’d rather have something else, it’s time to edit your own .bashrc file. Use the vi editor (you might need to flip to Section 4.3.2 in Chapter 4) to create a file called .profile in your home directory (/Users/yourname), and then add the following to the end of the file: export PS1="$ ". You can also change the prompt for a single session by invoking the command as follows:

Dave-Taylors-Computer:~ taylor$ PS1="$ "
$

This command will give you a simple, spare $ prompt with nothing else. (The % is traditional for shells derived from the Berkeley Unix C Shell, while $ is traditional for shells derived from the original Bell Labs Bourne Shell.) It’s not necessary—you could use a colon, a greater-than sign, or any other prompt character—but it is a nice convention, because it will immediately tell an advanced user what kind of shell you are using.

If that’s all you could do to set your prompt, it wouldn’t be very interesting, though. There are a number of special character sequences that, when used to define the prompt, cause the shell to print out various bits of useful data. Table 1-1 shows a partial list of these special character sequences for fine-tuning your prompt.

Table 1-1. Favorite escape sequences for bash prompts

Value

Meaning

\w

The current working directory

\W

The trailing element of the current working directory, with ~ substitution

\!

The current command history number

\H

The full hostname

\h

The hostname up to the first dot

\@

Time of day in 12-hour (a.m./p.m.) format

\A

Time of day in 24-hour format

\u

The username

\$

A # if the effective user ID is zero (root), or a $ otherwise

Experiment and see what you can create that will meet your needs and be fun too. For many years, a popular Unix prompt was:

$ PS1="Yes, Master? "

It might be a bit obsequious, but on the other hand, how many people in your life call you “Master”?

One prompt sequence that we like is:

$ PS1="\W \! \$ "

This prompt sequence shows the current working directory, followed by a space and the current history number, and then a $ or # to remind the user that this is bash and whether they’re currently running as root. For example, the prompt might read:

/Users/taylor 55 $

This tells you immediately that /Users/taylor is the current directory, and that you’re on the 55th command you’ve executed. (Because you can use the arrow keys to scroll back to previous commands, as described in Section 2.1.3 in Chapter 2, this is no longer as important, but there is a very powerful command history syntax built into bash that allows you to recall a previous command by number. If you’re familiar with this syntax, making the command history number part of the prompt can be handy.) On multiuser systems, it’s not a bad idea to put the username into the prompt as well, so you always know who the system thinks you are.

Creating Aliases

The flexibility of Unix is simultaneously its greatest strength and downfall; the operating system can do just about anything you can imagine (the command-line interface is certainly far more flexible than the Finder!) but it’s very difficult to remember every single flag to every command. That’s where shell aliases can be a real boon. A shell alias is a simple mechanism that lets you create your own command names that act exactly as you desire.

For example, we really like the -a flag to be included every time we list a directory with ls, so we created an alias:

$ alias ls="/bin/ls -a"

This indicates that each time we type ls in the shell, the /bin/ls command is going to be run, and it’s going to automatically have the -a flag specified. To have this available in your next session, make sure you remember to add the alias to your .profile file.

You can also have aliases that let you jump quickly to common locations, a particularly helpful trick when in Mac OS X:

$ alias desktop="cd ~/Desktop"

Chapter 4 describes the cp, mv, and rm commands, which copy, move, and remove files, respectively. Each of these support the -i switch, which will prompt you before overwriting or deleting a file. You can use aliases to always enable this switch:

$ alias rm="rm -i"
$ alias cp="cp -i"
$ alias mv="mv -i"

You can list active aliases all by typing alias without any arguments:

$ alias
alias cp='cp -i'
alias desktop='cd ~/Desktop'
alias ls='/bin/ls -a'
alias m2u='tr '\''\015'\'' '\''\012'\'''
alias u2m='tr '\''\012'\'' '\''\015'\'''

Have an alias you really want to omit? You can use unalias for that. For example, unalias ls would remove the -a flag addition.

Setting the Terminal Title

You can change the current Terminal title using the following cryptic sequence of characters:

echo '^[]2;My-Window-Title^G'

To type the ^[ characters in bash, use the key sequence Control-V Escape (press Control-V and release, then press the Escape key). To type ^G, use Control-V Control-G. The vi editor supports the same key sequence.

Such cryptic sequences of characters are called ANSI escape sequences. An ANSI escape sequence is a special command that manipulates some characteristic of the Terminal, such as its title. ^[ is the ASCII ESC character (which begins the sequence), and ^G is the ASCII BEL character. (The BEL character is used to ring the Terminal bell, but in this context, it terminates the escape sequence.)

Using AppleScript to Manipulate the Terminal

AppleScript is a powerful programming language used to automate Mac OS X applications. The Mac OS X Terminal is one such application. You can run AppleScript commands at the shell prompt using the osascript utility. The \ character tells the shell that you want to enter a single command on several lines (when you use this, the shell will prompt you with a ? character):

               osascript -e \
               'tell app "Terminal" to set option of first window to value'

For example, to minimize your current Terminal window:

$ osascript -e \
> 'tell app "Terminal" to set miniaturized of first window to true'
$

For a complete list of properties you can manipulate with AppleScript, open the Script Editor (/Applications/AppleScript) and select File Open Dictionary. Open the Terminal dictionary and examine the properties available under window. If a property is marked [r/o], it is read-only, which means you can’t modify it on the fly.

Working with .term Files

A quite useful capability of Terminal is the ability to create a specific Terminal window, customize its appearance and behavior, and then save that configuration as a .term file. Later, simply double-click on the .term file and you’ll have your Terminal window back and ready to go, exactly as you set it up previously. Even better, you can set up multiple windows and have them all saved into a single .term file and then collectively relaunched when you restart the Terminal program.

As an example, we have set up the main Terminal window exactly as we prefer — large, blue text on a white background — and would like to save it as a .term file. To accomplish this, choose File Save As. You’ll be prompted with the dialog shown in Figure 1-12.

Saving a .term file

Figure 1-12. Saving a .term file

Perhaps the most interesting option is the checkbox “Open this file when Terminal starts up”. Set things up the way you want and automatically, every time you start up Terminal, you could find a half dozen different size and different color windows on your desktop, all ready to go. Further, notice that instead of having a shell, you could have some start up running specific commands. A popular command to use is top or tail -f /var/log/system.log, to help keep an eye on how your system is performing. Explore the pop-up menu too; that’s where you choose a single window to save as a .term, or specify “All Windows” to save them all in a single .term file.

Get Learning Unix for Mac OS X Panther now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.