fcd: A Smart Change Directory
Command interfaces such as the UNIX shells give the
user a lot of
power and flexibility, but they are demanding. Along
names and parameter syntax, users have to remember (and
and complicated directory paths. Most users of the Korn
or C shell
become very adept at using the history functions to
keystrokes, but at best the history functions only let
you avoid typing
a long directory twice (you still have to type it correctly
Some users create aliases and environment variables
for certain directories,
but if there are many directories, this method becomes
have written an extension to the Korn shell cd command,
fcd, that can free the user from ever typing a full
fcd determines the full path when given a substring,
"cd's" to the full path.
fcd maintains a database of full paths to directories.
the user enters a path to fcd, fcd looks for that
path as a substring in a longer path. If an exact match
fcd can go to that directory immediately. Unfortunately,
substring is usually ambiguous -- that is, it is contained
than one full path. By default fcd minimizes ambiguities
assuming that the substring typed is the name of the
of the corresponding full path. In this mode, if you
bin", a possible destination is /usr/bin, but not
The deepest subdirectory in a path is the last part
of the path, so
all fcd has to do is look for a match at the end of
(a trivial task for grep).
Where an ambiguity exists at the deepest subdirectory
resolves it by letting the user pick the full path from
a list. For
example, suppose your file system (and the fcd database)
/usr/ed/apps/bin and /usr/bin. If you enter "fcd
bin", fcd presents the following message:
1 : /usr/bin
2 : /usr/ed/apps/bin
Which of the above do you mean (enter number or 'q' for none)?
fcd uses a database of directory paths because
it would take too long to search the file system each
time it gets
called. fcd in effect does the search ahead of time.
this makes fcd work very quickly, the database may not
the actual state of the file system, especially if directories
added and deleted frequently. When it finds a discrepancy,
can update its database to make the correction.
fcd adds to its database in several ways. When it is
run, and no database exists, it creates one by scanning
all the directories
in the user's $HOME directory. Later, if the user types
a directory name that is not in the database, fcd prompts
for the full path of the directory, which it then adds
to the database.
fcd also adds to the database when the -p and -r
flags (discussed below) are used.
fcd deletes from its database in two situations. First,
the user chooses "q" to quit after getting
a list of possible
directories, fcd sorts and checks all lines in input,
any duplicates. Second, if fcd attempts to change to
that no longer exists, it deletes that line from the
Several options make fcd more useful. These options
by single letter commands, preceded by the ("-")
The -e option overrides the standard search method of
It causes fcd to use extended search mode. Instead of
at the end of each line, fcd searches the entire line.
is useful if the user wants to type in only the middle
part of a long
directory name, or to get a list of many directories
under a certain
directory. The drawback is that too many matches are
For example, for "fcd -e bin" (using the same
as in the previous example), fcd presents a list of
/usr/ed/apps/bin, and all the directories under those
plus any other directory that contains the string "bin"
in the middle, including a name like /apps/binary.
The other two options log new directories. When you
use these options,
fcd does not process other arguments. The -p option
logs the current directory. The -r option makes fcd
recursively add the current directory and all its subdirectories.
To add the entire file system to the fcd directory,
could go to the root directory and type "fcd -r".
fcd is able to change directories because it runs in
process. For this reason, it probably should not be
a normal shell
script. A shell script is run as a child process of
your shell, and
environment changes made in the child process (including
directory) do not affect the parent. The dot (".")
allows you to run a shell script in the current process,
but it is
inconvenient for the user to type ". fcd directory".
method is to make fcd a function. The first version
was created on an NCR3000. The AT&T SVR4 UNIX running
on the system
allowed the use of the ksh autoload command to load
fcd into the shell environment. Unfortunately, this
work properly on our SCO UNIX, so fcd is now in the
The .kshrc file should be loaded automatically by ksh
when a new shell is spawned. If .kshrc is not automatically
loaded on your system, you may need to set the ENV variable
in your .profile. If this still does not work, you should
be able to run .kshrc by entering ". .kshrc"
logging in. Once fcd is loaded, no further setup is
The database is created and updated through normal use.
You only have
to be careful not to delete the file fcd.list from your
The .kshrc file in Listing 1 includes the function fcd
plus the necessary support functions. Code at the top
of the file
prevents fcd from being loaded into subshells. Without
code, many programs that spawn subshells would load
display the fcd banner. For this reason, if you are
using .kshrc, the listing should come after any code
executed for each subshell.
The first function in the file is addline. This is called
when a directory must be added to the database by the
user. Next is
a usage function that is called when fcd is run without
arguments. The last function is fcd itself. fcd starts
by checking for special case parameters. One special
case is the slash
character (/). Since the slash character is in every
full path, fcd
assumes that the user who types "fcd /" wants
to change to
the root rather than get a list of every directory in
The rest of the special cases handle the options to
that only -e does not exit immediately after processing;
and -r ignore extra parameters.
After processing the special cases, fcd checks if the
database file exists. If not, it creates one in the
user's home directory
using the find command. If you want the default database
to have different contents you can change $HOME in the
find command to something else. For example, if changed
"/", then the entire file system will be stored
in the database.
This is probably not necessary, since most users only
visit a fraction
of the directories on a system. find automatically skips
that the user cannot access, so "bad" directories
be added to the database.
Next fcd searches for the user's input using grep.
If the user types the "-e" flag, the entire
line is searched,
otherwise just the end of the line is checked. The string
in a temporary file ($Duplist). The duplist file is
counted to see how many matches are found. The best
case is exactly
one match, and the entire list is used for the match.
If there are
no matches, the user is informed, and invited to enter
the full path
of the directory to add to the database. If multiple
*) are found, awk is used to print the list with numbers,
and sed gets the line associated with the typed number.
the user doesn't want any of the listed directories,
the function without changing directories, but the database
and duplicates are removed. Finally, if a match has
been found, fcd
prints the match on the screen and changes to that directory.
cd command fails (the directory has been deleted or
have been changed), fcd deletes the directory name from
fcd could be improved in several ways. The biggest shortcoming
is that the fcd database does not automatically reflect
in the system's file structure. This is a difficult
problem to solve
because frequent scanning would cause the program to
run very slowly.
A useful improvement would be to allow interactive editing
fcd database. The user can currently use vi to add
or delete records from the database, but it would be
for deletions, if the program had a friendly interface
for this operation.
Another useful feature would be to let the user control
in which duplicate matches are displayed. Perhaps the
most often used
directories could filter to the top of the list. Finally,
representation of the directory structure would be a
Most MS-DOS programs that work similarly to fcd show
directory as a tree, with levels that may be expanded
using the cursor keys.
About the Author
Fred Brunet has a B.S. in computer science from California
State University, Northridge and is currently a C and
working on UNIX and MS-DOS platforms for jeTECH Data
Systems in Moorpark,