bash on Mac OS X
Pages: 1, 2
Regular Variables
A regular variable typically holds a piece of information that you use
frequently. Because variables in shell scripts are loosely typed, unlike
C and Java, variables
can hold virtually anything: a number, string, or composite value such
as an array or hash. Creating a variable is pretty painless: name=value,
and retrieving its value is almost as easy: $name.
Thus, if you wished to see the current date when opening a new Terminal window, you could place the following lines in your profile:
mydate=`date "+%H:%M:%S %m/%d/%y"`
echo "hi $USER, the current time is $mydate"
For more information on shell scripting, refer to Chris Stone's series of articles mentioned in the introduction.
Environment Variables
Environment variables are essentially a special case of shell variables; they are visible to all child processes that are spawned from the shell. In layman's terms, this means that applications and scripts that are executed from within shell can read the value of the shell's environment variables; as a result, command-line tools typically use environment variables for configuration settings.
By convention, the names of environment variables are all uppercase. Environment variables on OS X may include the following:
| Variable Name | Description | Example |
|---|---|---|
| PATH | A list of colon-separated directories where the shell will look for executable files | /bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin |
| CLASSPATH | A list of colon-separated directories and/or JAR files that contain Java class files that may be required in the Java Runtime Environment. | /Users/dave/FVL/Java/xerces.jar: /Users/dave/FVL/mckoi.jar |
| JAVA_HOME | The root directory of your Java installation. | /Library/Java/Home |
| PWD | Your current directory in the file system. | /Applications |
| USER | Your login name. | dave |
To find out which environment variables have been defined in your shell,
use the env command, which simply echoes all the environment
variables to the terminal:

Figure 4: All environment variables defined in my shell.
Creating new environment variables is pretty simple; bash uses
the syntax export VAR_NAME=value. Thus any shell variable
can be turned into an environment variable via the export
command:
# create the JAVA_HOME environment variable
export JAVA_HOME=/Library/Java/Home
# do the same thing explicitly, using two lines
JAVA_HOME=/Library/Java/Home
export JAVA_HOME
And what happens if a required environment variable doesn't exist? Nothing too drastic -- the kernel won't panic and your computer won't start blowing smoke. It shouldn't, anyway. The shell and related tools require certain variables to be defined (such as ), but other tools may need their own environment variables. In the event that you are missing a required variable, chances are the related program will fail safely and let you know what needs to be defined, as does Apache's fop:

Figure 5: A typical example of missing an environment
variable.
The following table lists the differences in working with variables (both shell and environment variables) between tcsh and bash on OS X:
| Command | tcsh | bash |
|---|---|---|
| Display all shell variables | set |
set |
| Create a shell variable | set name=value |
name=value |
| Remove a shell variable | unset name |
unset name |
| List all environment variables | env |
env |
| Create an environment variable | setenv name value |
export name=value |
| Remove an environment variable | unsetenv name |
unset name |
Aliases
Aliases have been a part of Mac OS for several generations now. However, the terminology has gotten a bit confusing with Mac OS X since it's a branch between two traditionally distinct family trees: Unix and Mac OS, each with their own vocabulary. So it shouldn't be too much of a surprise that bringing the two together results in some conflict. One example of this is the term alias: the Finder and Unix underbelly each use the term for two different things:
- In the Finder, aliases make it convenient to access a file that is somewhere else on your hard drive; an alias essentially allows you to access the same file from multiple places.
- Aliases in shells serve a similar purpose, but because they exist
in a text-only environment, their role is a little different (the
Unix equivalent of the Finder's alias is called a
link); shell aliases allow you to remap virtually any Unix command to another name, and the aliased commands can then be invoked using their new name.
Aliases are declared in a similar method to variables, with the keyword
alias in front of the declaration: alias name=command.
If the command contains spaces, then you will have to wrap it in double
quotes. To find out which aliases you have already defined, simply enter
the command alias (in the event that you wish to remove
an alias, then you can simply use the command unalias name):
alias l="ls -l"
alias ll="ls -al"
alias ~="cd ~"
alias md=mkdir
alias mckoi="java com.mckoi.runtime.McKoiDBMain "
# remove the alias named md (for demonstration purposes)
unalias md
The following image illustrates the use of the first two aliases created above:

Figure 6: An example of how even simple aliases can
save you time at the keyboard.
Setting Your Prompt
After opening a Terminal window and being greeted by the message of the day, the first thing you'll see is your command prompt, waiting to accept your every wish. If you went ahead and changed your prompt in Jaguar with tcsh, chances are you'll be disappointed when you first see Panther's default prompt, which should appear something like:

Figure 7: The default prompt for bash in Panther.
Like tcsh, however, it is a relatively trivial process to change
your prompt in bash by setting the value of two special shell
variables, PS1 and PS2. Why two, you may ask?
Good question -- PS1 is can be considered to be the primary
prompt, which is displayed every time a new command can be
entered; while PS2 is the secondary prompt that is displayed
when a command spans more than one line. This screen shot illustrates
the two prompts in use:

Figure 8: An illustration of PS1 and PS2
in bash's default configuration.
The following table lists the information that you may wish to insert into your prompt:
| Command | Description | Example |
|---|---|---|
| \a | ASCII bell character | -- |
| \d | the current date | Sun Feb 08 |
| \H | hostname | Ginger.local |
| \h | shortened hostname | Ginger |
| \u | your username | dave |
| \w | current working directory | /Applications/Network |
| \W | basename of the current working directory | Network |
| \T | current time (12-hour HH:MM:SS format) | 01:16:49 |
| \t | current time (HH:MM:SS format) | 13:16:49 |
| \@ | current time (12-hour AM/PM format) | 1:16 PM |
| \n | new line | -- |
| \\ | print a backslash | \ |
From the information listed in the above table, we can see that Panther's default prompt strings are created using the following commands:
PS1="\h:\w \u$ "
PS2=" > "
Wrapping Up
This article provides an overview on making the transition from tcsh and bash; at this point you should now know enough about bash to start tailoring your Panther environment to your needs. And while this article covers several key features of it, we have barely scratched the surface; command history, job control, scripting, and several other features went untouched. For more information, be sure to check out the following resources:
- As with most Unix programs, the bash documentation is installed
along with the program itself, and it can be found in the man pages.
Simply type the command
man bashat the prompt to read the pages. - The Free Software Foundation's web site hosts the complete manual for the bash shell.
- Learning the bash Shell, 2nd Edition by Cameron Newham & Bill Rosenblatt (O'Reilly & Associates, 1998) provides an in-depth introduction to the basics of shells, and then goes on to cover everything you would ever need to know about bash.
David Miller is combining his passions of photography and working on the web at iStockphoto; when not hacking away with a text editor and a few web browsers in hand, he can be seen huddled over his laptop tweaking levels and curves for his freelance photography. Keep track of David's latest projects over at his home on the web.
Return to the Mac DevCenter
You must be logged in to the O'Reilly Network to post a talkback.
Showing messages 1 through 13 of 13.
-
bash_profile
2006-06-10 01:11:37 nitewing98 [Reply | View]
The file .profile didn't seem to execute when I started a Terminal session. However, the file .bash_profile does execute.
Am I looking at the wrong file? What's the difference (if any)?
-
RCEnvironment
2004-03-18 10:46:29 xyzzy-xyzzy [Reply | View]
If you want an GUI way to set up environment variables on Mac OS X, you should check out RCEnvironment (look it up in versiontracker.com).
It's a Preference Pane that lets you enter your environment variables, even when you aren't in a shell.
-
iTerm
2004-02-27 10:50:46 jeblanton [Reply | View]
Great summary, but I have to say that I was surprised that iTerm wasn't mentioned -- it's by far the best terminal client for OS X -- certainly must better than the one it ships with.
-
Come to where the flavour is...
2004-02-25 16:11:51 pmccann [Reply | View]
Come to zsh country. Seriously, if you're looking at learning a new shell (bash from tcsh, say), have a good look at zsh first. It's a seriously comfortable environment in which to live: the effort spent getting things set up in the first place is repaid many times over down the track. A huge number of really nice features *just work* in zsh, but this TEXTAREA is too small to contain a list of them: hey, maybe a nice future article?
((ps isn't there something a little *weird* about putting all the initialisations into one file? I know it's *necessary* in bash, in that the .bashrc is only executed in a non-login shell. But if .profile is used, as in the article, then any subshells are going to be alias free. And if you plonk everything in .bashrc then it won't be executed for a login shell, and that PATH variable is going to be appended to when you execute any subshell. One solution that pops to mind: separate out the bits that should be executed once from those things that need to be set every time a new shell is spawned. That is: environment variables in the first (.profile) and aliases et al in the second (.bashrc), and then add a line "source .bashrc" to the end of your .profile. Two files... multiply your fun. (All this should be read as if spoken by a character in a geeky novel.) Corrections and better suggestions welcome!))
-
main question is..why use bash?
2004-02-25 09:52:06 pteeter [Reply | View]
This comment may incite a holy war among the shells. But, why switch to bash? tcsh offers the best of csh and ksh - file completion (set filec) and command line history recall (ESC, up arrow / down arrow).
Using either niutil or NetInfo Manager one can easily restore their default shell to /bin/tcsh.
niutil -createprop . /users/pteeter shell /bin/tcsh
-
if only ...
2004-02-25 08:09:07 henksmets [Reply | View]
... I could do this in bash
alias precmd 'printf "\033]0;%s @ $SHORTHOST\007" "${cwd}" | sed -e "s%$HOME%~%"'
sched +0:00 alias postcmd 'printf "\033]0;%s @ $SHORTHOST\007" "\!#"'
This gives me dynamic hostname information in the terminal information. When I ssh to a server that terminal window is easily recognisable. -
if only ...
2004-02-25 08:54:46 blalor [Reply | View]
But you can!
if [ "${TERM#xterm}" != "${TERM}" ] && [ "${EMACS}" != "t" ]; then
# Set prompt to "[$USER@$HOSTNAME `pwd` ]> "
prompt_command () {
# Display my current machine and directory in the title bar!
title="${LOGNAME}@$(hostname -s):[$(dirs)]"
echo -n "ESC]1;$title^G"
echo -n "ESC]2;$title^G"
}
export PROMPT_COMMAND=prompt_command
else
unset PROMPT_COMMAND
fi
(the ESC and ^G are actually control characters I entered in with Emacs; \033 and \007 would probably work, too.)
That gives you a prompt like[blalor@Animal ~]>and a window title likeblalor@Animal:[~] -
if only ...
2004-02-28 04:29:31 hysterion [Reply | View]
This does the precmd part. OTOH there is no bash equivalent for the postcmd part (used here to put the last command executed in the title bar).
This can be done in tcsh and zsh, but in bash there is simply no way unless you patch it. -
if only ...
2004-02-27 04:04:25 henksmets [Reply | View]
Great, thanks a lot, I looked a long time for this
I'm also looking for a way to colorize my different ssh-connections, with the same color for each host. I found some tips but someway it doesn't work. Are bash solutions?
http://www.macosxhints.com/article.php?story=20030625043920144
http://www.macosxhints.com/article.php?story=20030213071650891
-
correction
2004-02-25 00:07:11 housemaister [Reply | View]
for tcsh the 'Create an environment variable' command should look like:
setenv name value
(without =)
-
Check out screen
2004-02-24 23:38:59 adpsk [Reply | View]
You'll be happy you did...
http://www.gnu.org/software/screen/screen.html
-
User shell?
2004-02-24 19:12:52 keath [Reply | View]
I enjoyed the article. I've grown accustomed to tcsh, but always like learning more.
As for the method of setting shell preference, I use the NetInfo Manager found in /Applications/Utilities. 'There's more than one way to do it' of course, but it seems a good way to establish preferences for each user.






Error in <TApplication::ExecuteFile>: macro cin_rel_vale.c not found in path .:/Applications/root/macros:
i saw that it doesn't set some environment variables....i would like to know how can i modify in a permanent way this environment variables...
thanks