Can you just tell me how to add a value to the PATH without covering the
fuckin' history of Unix?
In bash/sh/ksh:
$ export PATH=$PATH:/new/directory/
In tcsh:
$ setenv PATH "$PATH:/new/directory/"
I honestly haven't used csh in so long that I've forgotten how to do it
in that shell. But I'll remember to install csh and try it.
Ok, how the hell does all that work?
What is a path?
A unix directory is a tree: it has a root directory (or folder for your windows
people) which contains files or subdirectories (subfolders). A specific file
can be uniquely located with the filename and the directory in which it resides,
that directory can in turn be uniquely located with the name and the directory
in which it resides, and so on. The full chain of directories in which a
file/folder resides is termed the (full) path to the file, or the path for
short. On unix, the "/" character separates each directory. For example, a
file "testfoo.txt" located in the directory "sbin", which in turn is located
in the directory "usr", which in turn is located in the root directory, can be
accessed as "/usr/sbin/testfoo.txt". Naturally, there are also relative paths
since the path to a particular file can be relative to where exactly in the
directory tree you are presently located in. I am assuming here that you have
used "cd" and "ls" and other filesystem utilities so you know conceptually
what I'm describing as a tree and a location.
What is $PATH?
In order for the command line to know exactly where a file is, it needs to know
the full path to that file (e.g. "/usr/sbin/testfoo.txt"). The command-line
interpreter knows where a file is because: (1) You tell it exactly where it is
by specifying the full path; or (2) The directory in which the file resides is
"in the PATH". In this case, the path refers to an environment variable
(we'll call it $PATH) which holds a set of directory paths. Each of these
entries (separated by a ':') represent directories in which the command-line
interpreter will search for files that aren't located via the full path or
relative path specified by the user. So when you type "useradd" at the
command-prompt, it searches inside every path in your $PATH. Note that if the
current directory (specified by a '.') is not in your path, it will not assume
that it should look in the current directory -- a lot of DOS folk have trouble
with this concept. If the file is not found in any of the directories specified,
then the command-line interpreter issues a "Command not found" error. And, if
you go on IRC, and hear something like "adduser is in /usr/sbin/ which is probably
not in your PATH" you now understand what I mean.
How do I add stuff to my PATH?
Well, the PATH is an environment variable. It contains a list of directory paths
each separated by the ':' character. So to add "/usr/sbin" to your path you
simply need to concatenate ":/usr/sbin" to the string currently held in environment
variable PATH. Now how you actually change environment variables depends on the
command-line interpreter you are using (we call the command-line interpreters
"shells" for short and some of the popular ones include bash,tcsh,ksh,csh,sh).
Shells belong to one of two families: (1) C Shells; and (2) Bourne Shells.
Shells like sh,ksh,bash are Bourne Shells and all have similar syntaxes;
Shells like csh, tcsh are C Shells and have their own syntax. So assigning values
to variables has a lot to do with which of the two types of shells you are
running on the system at the time. (This is not a trivial point since on some
systems, the startup scripts are written in sh which is a Bourne Shell so if
you personally run a C shell it's important to know how to set variables in both,
or atleast port stuff from one to the other as I do sometimes).
How do I change the value of environment variables in Bourne Shells?
Just like in programming class, you assign new values with the '=' operator.
So for example, you can type 'VARNAME = foo' to assign the string "foo"
to the variable name VARNAME. So if you want to assign '/usr/sbin' to your
path you simply:
$ PATH=/usr/sbin
But how do I add to the value of PATH without obliterating everything in it?
Firstly, if you obliterated your PATH you should excute another shell
(i.e. open another terminal) so that you start with a fresh copy of the
environment (which has PATH defined in it).
Well, to access values inside variables in Bash you simply put the '$' character
(I call it the subsitution operator but I'm sure it has a real name read your shell's
manpage for details). So $PATH refers to the values inside the PATH environment
variable. To keep that value in the new assignment, you simply reassign it to
itself:
$ PATH=$PATH:/usr/sbin
This means that PATH will become a variable with the old value for $PATH
followed by the special path delimeter character ':' and the path you wish
to add (in this case /usr/sbin). This means that the next time that you type
a command, the PATH will have grown to include the directory which contains the
command (which is just an executable on the filesystem).
Alternatively, you can place { } around the variable name you are trying to
access to delimit it from the rest of the characters. Therefore, this also works:
$ PATH=${PATH}:/usr/sbin
Lastly, there is the command EXPORT. This is a built-in shell command which
adds variables to the global environment. Therefore, to set the variable PATH
the global environment, you
$ export PATH
And since you can do this in one statement,
$ export PATH=$PATH:/usr/sbin
NOTE: Dealing with variables in shells is a fun topic in and of itself, and one that
I'd urge people to explore. They all demonstrate different ways of approaching
some basic architectural choices made when implementing a language, since these
shells are also full-fledged (as in Turing complete) programming languages.
Just read the man page for your specific shell to get into the details.
So what if I don't use a Bourne Shell? How do I change the path in a
C shell?
The same discussion from the Bourne Shell example applies to C shells.
The only issue is that the syntax for assigning and accessing variables
changes. To set an environment variable in C shells, you use the command
setenv instead of export. And, in C shells, the assignment is implied
so you don't need the '=' operator (the second thing in the command is
always the name of the variable being assigned to). Moreover, in certain
C shells the { } as delimeters for the variable name is mandatory. Hence:
$ setenv PATH ${PATH}:/new/directory/
How do I do it in whatever $SHELL I have?
I only really use Bash, and I have been favoring Kourne Shells for a while now,
so I can't really be of much help to people using all of the 10+ shells in
existence. But I'd be curious to see how different the process is, so you can
send me an email with the name of your shell and I can try and play around with
it and perhaps add it to this document.