As mentioned earlier, bash
is Mac OS X’s default Unix shell. Apple made the switch from tcsh
to bash
because of its support for Unicode text, something that’s very important in the international market. Another logical reason for switching to bash
is that it is the default shell for most Linux distributions and is easier to script with than tcsh
. Because bash
is now the default shell, this book focuses on its use, with an occasional nod to the other shells where appropriate.
The default configuration of bash
is perfectly adequate for casual usage, but you’ll inevitably want to configure it to your own liking. This section takes a look at the various configuration files for bash
, its environment variables
, how to set
up command aliases, and how to use bash
’s history to your advantage. You’ll also learn a bit about redirecting output between commands and into files, as well as some basic shell loops.
Every program on the system runs in an environment
. The environment consists of a set of name-value pairs, known as environment variables
, which communicate a variety of configuration settings to a program. For example, the shell uses the PATH
environment variable to find a program to execute in response to a command. To get an idea of what kinds of data are stored in environment variables, execute the set
command, as shown in Example 4-5.
Example 4-5. Examining environment variables with set
$ set
BASH=/bin/bash
BASH_VERSINFO=([0]="2" [1]="05b" [2]="0" [3]="1" [4]="release"
[5]="powerpc-apple-darwin8.0")
BASH_VERSION='2.05b.0(1)-release'
COLUMNS=80
DIRSTACK=()
EUID=501
GROUPS=()
HISTFILE=/Users/jldera/.bash_history
HISTFILESIZE=500
HISTSIZE=500
HOME=/Users/jldera
HOSTNAME=ronin.local
HOSTTYPE=powerpc
...
When you execute the set
command, you’ll see quite a bit of output—probably around 40 lines. Some of the environment variables may make sense when you first look at them, and some won’t. Table 4-6 lists some of the environment variables you are likely to use on occasion.
Table 4-6. Commonly used bash environment variables
Variable |
Description |
---|---|
|
Location of the |
|
Version of |
|
Number of columns to use in Terminal view |
|
List of directories used by the |
|
Various groups with which the user is associated |
|
File containing the shell history |
|
Home directory for the user |
|
Name of the system on which the shell is running |
|
Number of lines currently being used by the shell |
|
List of directories the shell uses to resolve commands |
|
String used as the primary prompt |
|
String used as the secondary prompt |
|
Shell program being used |
|
Options in effect for the shell |
|
Type of terminal that the shell is displaying its content to |
|
User ID of the currently logged-in user |
|
Username of the currently logged-in user |
|
Previously executed command |
To see the value of a single environment variable such as PATH
, you can use the echo
command, as shown in Example 4-6.
Example 4-6. Using the echo command to examine an environment variable
$ echo $PATH
/bin:/sbin:/usr/bin:/usr/sbin
The dollar sign in front of PATH
means you are referring to an environment variable. If you had just entered echo PATH
, the shell would return PATH
, as shown in Example 4-7.
To set or change an environment variable for the lifetime of the shell, use the export
command. For example, to change the PATH
variable so that you can run your own commands in ~/bin
, you could use the following command:
$ export PATH=$PATH:~/bin
This sets the PATH
variable to the currently existing PATH
with the ~/bin
directory appended to it. An important thing to remember here is that you need to use a colon (:
) as a delimiter between command paths
. These commands will last for the lifetime of the current shell, which is as long as that Terminal window is open. To add these paths to the shell permanently, you’ll have to edit one of bash
’s configuration files
, described next.
When bash
first starts, it looks for run command
files. Commonly called rc
files, Unix apps use these files to store basic configuration data that is used as the program loads. As a matter of fact, there are some special rc
files in the /etc
folder that are involved with the initial setup and loading of Mac OS X itself. You can learn some more about them in Chapter 5.
The bash
shell first looks at the /etc/profile
file for its initial state. This is a system-wide set of default settings that are superseded by any other files subsequently loaded by bash
. Next, three files in the Home directory, if they exist, are used to configure bash
:
-
.bash_profile
Contains environment variables and commands that are read and executed every time you create a new Terminal window and a shell is created for it, or when you SSH into your machine and are presented with a prompt. This allows you to customize the shell to your liking. If
bash
doesn’t find this file, it looks for.bash_login
and.profile
respectively to fill in for it.-
.bashrc
Contains environment variables and commands that are read and executed only when you create a subshell by typing
bash
in an already running shell.-
.bash_logout
Contains commands that are read and executed when you log out of a shell. You could use this to clean up files before you log out.
By default, these files don’t exist as part of a user’s Home directory until you create them. The most useful of these three files is .bash_profile
, which is used to customize the shell. For example, if you wanted to permanently modify the PATH
that the shell uses to resolve commands, you could create a .bash_profile
file in your Home directory and add the following line:
PATH=$PATH:~/bin:/Developer/Tools
This causes the PATH
environment variable to be set to the given string each time you open a new Terminal window. Because .bash_profile
is only read when the shell is created, any changes you make to it won’t take effect until you start the next shell. If you don’t want to close your shell and start a new one, you can use the source
command to load the contents of the .bash_profile
file:
$ source ~/.bash_profile
In addition to searching the PATH
for commands, the bash
shell lets you define a set of aliases
. Aliases are commonly used to create a shorter command name for long command strings so that they’re a bit more manageable or to rename commonly used commands. It’s important to note that these are not the same aliases as those defined in the Finder. Finder aliases are closer to the Unix concept of a symbolic link. It’s a shortcut to a file instead of a shortcut for a command.
To define an alias
for a command, use the following syntax:
alias name=command
Where name
is the name of the command
alias you are defining, and command
is the command that’s actually executed by the shell when you invoke the alias. One common use of aliases is to accommodate fat-fingering of commands. For example, if you are always typing sl
instead of ls
, you could define the following alias so that you don’t get scolded by the shell again:
$ alias sl=ls
Another use for aliases is to create a simple command for a longer one. For example, if you are often changing directories to somewhere deep in the hierarchy, you can set up an alias that will allow you to go there quickly:
$ alias fdocs="cd ~/Documents/Corporate/Master/Forecasts"
Notice the use of quotes around the command. This is required when a command consists of more than one word.
Yet another use for aliases is to redefine a command to add some default options. For example, if you’re constantly forgetting about the hidden dot files on your machine, you can redefine the way the shell handles the ls
command:
$ alias ls="ls -a"
As another example, if you’re still getting used to the fact that the shell doesn’t make use of the Trash can, you can make the rm
command ask you to confirm file deletions by using its -i
switch:
$ alias rm="rm -i"
To get a list of all the aliases currently defined, use the alias
command by itself, as shown in Example 4-8.
Example 4-8. Examining the currently defined shell aliases
$alias
alias sl=ls
alias fdocs="cd ~/Documents/Corporate/Master/Forecasts"
You can even make aliases to GUI applications. For example, if you wanted to create a quick shortcut to open the Safari browser while on the command line, you could define the following alias:
$ alias safari="open -a Safari"
With this alias in place, to launch Safari, you simply need to type safari
into the command line. And remember, to make an alias permanent, you’ll need to create a .bash_profile
file and place the alias into it or edit your existing .bash_profile
file and then source
it so the change takes effect.
As bash
runs, it keeps a history
of the commands that you’ve executed. This feature is quite handy as it lets you look at and reuse commands that you’ve previously entered. Where the shell’s history is particularly useful is when you need to invoke a command that has a lengthy set of parameters that you can’t remember.
The simplest way to use the history is to use the up and down arrows on your keyboard. This will step back and forth through the commands that you’ve executed and display each in turn at the prompt. To get more out of the history, you can use the history
command, which displays a list of previously executed commands. Example 4-9 shows some output from history
.
The commands are listed in the order in which they were executed. To reuse a particular command, type !
(exclamation point; also called “bang” by Unix geeks), followed by the number of the command you want to reuse. Example 4-10 shows how to use this command.
Example 4-10. Using a command from the history
$!2
ls
Adobe SVG 3.0
Installer Log
Music
Desktop
Pictures
Documents
Public
Library
Sites
Movies
Work
Note that the shell tells you which command is running as it runs the command. This is useful because you can tell what arguments are being used. Another way to navigate the history list is to use the first few letters of the command instead of the command number. Example 4-11 shows how to quickly execute the last command that started with an o character.
Whenever you exit bash
, it writes its history to the ~/.bash_history
file. Likewise, whenever you start bash
, it populates its history with the contents of the ~/.bash_history
file. This allows you to quit and restart your shell and still have your history available to you. By default, the history file is set to retain up to the last 500 commands. To change this value, set the HISTFILESIZE
environment variable to the number of lines that you want to keep. For example, to change it to remember 1,000 commands instead of 500, you would use the following:
$ export HISTFILESIZE=1000
Once again, if you’d like to make this change permanent, you’ll have to add it to your ~/.bash_profile
file.
If you’ve been using the shell for a while, the history
command might have so many entries to display that they scroll by too quickly for you to read them. Earlier in the chapter, you learned about the more
command. It might have occurred to you that this would be a perfect opportunity to use more
to paginate the history
command’s output. However, it may not have been immediately obvious how to do so.
This is where one of the most powerful features of the Unix shell comes into play. The shell allows you to redirect the output from one command and pass it along to another command. It also enables you to redirect a command’s output to a file for later perusal. For example, if the history
command’s output is scrolling too quickly for you, you could redirect its output to the more
command as follows:
$ history | more
The pipe (|) character is used for passing the data between commands. For saving the output to a file, you’d use the greater than character (>). So if you wanted to save a directory listing of your /Applications
folder to a file on your Desktop, use the command:
$ ls -l /Applications > ~/Desktop/DirectoryListing.txt
You can even append output from a command to the end of a file by using two greater than symbols (>>). If you want to add the directory listing of your /Applications/Utilities
folder to the file on your desktop:
$ ls -l /Applications/Utilities >> ~/Desktop/DirectoryListing.txt
For some fun with redirecting data between commands, try using the ls
command to send a directory listing to the say
command. Just make sure your speakers are on to hear the results.
Another powerful feature the shell gives you is the ability to loop through commands. This will come into play more in Chapter 13 when shell scripts are covered, but for now, here’s a basic example of a loop. Let’s say that you have several text files on your Desktop that you want the say
command to read aloud to you. After reading the discussion of wildcards earlier in the chapter, you might think the following command would work:
$ say ~/Desktop/*.txt
However, executing that command will make say
merely speak the files’ names, not read the files’ contents to you. To have each file read aloud, you need to supply each file’s name to the say
command, using only one file each time you issue the command. This can quickly become tedious if you have several files you want to have read aloud.
If you enter the shell commands shown in Example 4-12, you can make the shell do all of that work for you:
The first line of this loop starts with the for
command, which tells bash
that we’re defining a loop. The next value, i
, is a temporary variable to hold a single file’s name. The in
portion tells for
that the part that follows, $(ls ~/Desktop/*.txt)
, is where it should look for the values to place in i
. The $()
convention is used to have the shell place the output of one command (in this case, ls ~/Desktop/*.txt
) into another, but isn’t quite the same as redirecting the output using a pipe.
The do
line indicates to the shell that the commands that follow are the contents of the loop. The loop is closed with a simple done
command. When executed, the shell will use the ls
command to find all files in ~/Desktop
that end in .txt
. The shell will then take the first result, store it in the variable i
, and process the commands between do
and done
. Once the commands have been executed, the shell takes the next value from the directory listing results, places it in the i
variable, and then loops through the commands again.
Get Running Mac OS X Tiger 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.